将字符串解析为枚举类型

时间:2009-09-15 03:30:01

标签: c# .net generics enums

我有一个像这样的枚举类型作为例子:

public Enum MyEnum {
    enum1, enum2, enum3 };

我将从配置文件中读取一个字符串。我需要它来解析字符串到MyEnum类型或null o未定义。不确定以下代码是否有效(对不起现在无法访问我的VS):

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

不确定它是否正确或是否有其他简单的方法将字符串解析为MyEnum值?

8 个答案:

答案 0 :(得分:31)

如下:

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

用作:

MyEnum? value = EnumUtils.Parse<MyEnum>("foo");

(注意:旧版本在try/catch周围使用了Enum.Parse

答案 1 :(得分:5)

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

输出:

    //This line is empty as Enum11 is not there and function returns a null
Enum1
TestApp.Program+MyEnum
Enum10
Press any key to continue . . .

答案 2 :(得分:4)

这是一个老问题,但现在.NET 4.5有Enum.TryParse()。

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

答案 3 :(得分:2)

如果你使用的是.NET 3.5(甚至2.0,如果你修改了扩展方法),我对本文中的技术运气很好:

枚举和字符串 - 停止疯狂!

编辑:域名已经消失,现在是一个链接农场。我从工作中的代码库中提取代码(稍加修改并随时间添加),您现在可以在这里找到:

https://gist.github.com/1305566

答案 4 :(得分:2)

我在UnconstrainedMelody中有一个TryParseName方法,一个用于委托和枚举实用程序方法的库,它通过一些postbuild技巧使用“难以形容的”约束。 (代码使用库不需要postbuild,只是为了清楚。)

您可以这样使用它:

Foo foo;
bool parsed = Enums.TryParseName<Foo>(name, out foo);

我目前没有不区分大小写的版本,但如果您愿意,我可以轻松地介绍一个版本。请注意,此不会尝试解析数字,例如“12”就像内置版本一样,也不会尝试解析以逗号分隔的标志列表。我可能会在以后添加标志版本,但我在数字版本中看不到多少点。

这是在没有装箱且没有执行时间类型检查的情况下完成的。拥有约束非常方便:)

如果您发现不区分大小写的解析有用,请告诉我。

答案 5 :(得分:2)

我刚刚将here的语法与here的异常处理结合起来创建了这个:

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

您可以稍微旋转一下以返回null而不是抛出异常。

答案 6 :(得分:1)

如果您想避免使用try / catch,可以使用TryParse

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

我稍微修改了选定的答案。我希望你喜欢它。

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

答案 7 :(得分:0)

要按字符串返回枚举,如果包含:

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