Parse string to enum type

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 need it to parse the string to MyEnum type or null o not defined. Not sure if the following codes will work (sorry for not having access to my VS right now):

// example: ParseEnum<MyEnum>("ENUM1", ref eVal);
bool ParseEnum<T>(string value1, ref eVal) where T : Enum
{
  bool bRet = false;
  var x = from x in Enum.GetNames(typeof(T)) where 
       string.Equals(value1, x, StringComparison. OrdinalIgnoreCase)
       select x;
  if (x.Count() == 1 )
  {
    eVal = Enum.Parse(typeof(T), x.Item(0)) as T;
    bRet = true;
  }
  return bRet;
}

Not sure if it is correct or there is any other simple way to parse a string to MyEnum value?

Answers


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)


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 . . .

This is an old question, but now .NET 4.5 has Enum.TryParse().

http://msdn.microsoft.com/en-us/library/dd991317.aspx


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...


I have just combined the syntax from here, with the exception handling from here, to create this:

public static class Enum<T>
{
    public static T Parse(string value)
    {
        //Null check
        if(value == null) throw new ArgumentNullException("value");
        //Empty string check
        value = value.Trim();
        if(value.Length == 0) throw new ArgumentException("Must specify valid information for parsing in the string", "value");
        //Not enum check
        Type t = typeof(T);
        if(!t.IsEnum) throw new ArgumentException("Type provided must be an Enum", "TEnum");

        return (T)Enum.Parse(typeof(T), value);
    }
}

You could twiddle it a bit to return null instead of throwing exceptions.


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


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;
    }
}

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);
    }

Need Your Help

How to make primary key as autoincrement for Room Persistence lib

android kotlin android-room

I am creating a Entity(Room Persistence lib) class Food, where i want to make foodId as autoincrement.

Fail to convert to internal representation

java eclipse oracle hibernate tomcat

I am bringing up Broadleaf Commerce application using Oracle Database and Tomcat 6 server.