I have an enum type like this as an example:
public Enum MyEnum {
enum1, enum2, enum3 };
I\'ll read a string from config file. What I n
private enum MyEnum
{
Enum1 = 1, Enum2 = 2, Enum3 = 3, Enum4 = 4, Enum5 = 5, Enum6 = 6,
Enum7 = 7, Enum8 = 8, Enum9 = 9, Enum10 = 10
}
private static Object ParseEnum<T>(string s)
{
try
{
var o = Enum.Parse(typeof (T), s);
return (T)o;
}
catch(ArgumentException)
{
return null;
}
}
static void Main(string[] args)
{
Console.WriteLine(ParseEnum<MyEnum>("Enum11"));
Console.WriteLine(ParseEnum<MyEnum>("Enum1"));
Console.WriteLine(ParseEnum<MyEnum>("Enum6").GetType());
Console.WriteLine(ParseEnum<MyEnum>("Enum10"));
}
OUTPUT:
//This line is empty as Enum11 is not there and function returns a null
Enum1
TestApp.Program+MyEnum
Enum10
Press any key to continue . . .
If you're using .NET 3.5 (or even 2.0, if you trim out the extension method), I've had great luck with the techniques in this article:
Enumerations and Strings - Stop the Madness!
EDIT: Domain is gone and is now a link farm. I pulled the code (slightly modified and added to over time) from our codebase at work, which you can now find here:
https://gist.github.com/1305566
To return Enum by string, if contains:
public static T GetEnum<T>(string s)
{
Array arr = Enum.GetValues(typeof(T));
foreach (var x in arr)
{
if (x.ToString().Contains(s))
return (T)x;
}
return default(T);
}
You can use TryParse
if you want to avoid using try/catch.
MyEnum eVal;
if (Enum.TryParse("ENUM2", true, out eVal)){
// now eVal is the enumeration element: enum2
}
//unable to parse. You can log the error, exit, redirect, etc...
I modified the selected answer a little bit. I hope you like it.
public static class EnumUtils
{
public static Nullable<T> Parse<T>(string input) where T : struct
{
//since we cant do a generic type constraint
if (!typeof(T).IsEnum)
{
throw new ArgumentException("Generic Type 'T' must be an Enum");
}
int intVal;
if (!string.IsNullOrEmpty(input) && !int.TryParse(input, out intVal))
{
T eVal;
if (Enum.TryParse(input, true, out eVal))
{
return eVal;
}
}
return null;
}
}
What about something like:
public static class EnumUtils
{
public static Nullable<T> Parse<T>(string input) where T : struct
{
//since we cant do a generic type constraint
if (!typeof(T).IsEnum)
{
throw new ArgumentException("Generic Type 'T' must be an Enum");
}
if (!string.IsNullOrEmpty(input))
{
if (Enum.GetNames(typeof(T)).Any(
e => e.Trim().ToUpperInvariant() == input.Trim().ToUpperInvariant()))
{
return (T)Enum.Parse(typeof(T), input, true);
}
}
return null;
}
}
Used as:
MyEnum? value = EnumUtils.Parse<MyEnum>("foo");
(Note: old version used try/catch
around Enum.Parse
)
I have a TryParseName
method in UnconstrainedMelody, a library for delegate and enum utility methods which uses "inexpressible" constraints via some postbuild trickery. (Code using the library doesn't need a postbuild, just to be clear.)
You would use it like this:
Foo foo;
bool parsed = Enums.TryParseName<Foo>(name, out foo);
I don't currently have a case-insensitive version, but I could easily introduce one if you wanted. Note that this doesn't try to parse numbers e.g. "12" like the built-in version does, nor does it try to parse comma-separated lists of flags. I may add the flags version later on, but I can't see much point in the numeric version.
This is done without boxing and without execution time type checking. Having the constraint is really handy :)
Please let me know if you'd find a case-insensitive parse useful...