将字符串解析为枚举类型

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

public Enum MyEnum { enum1, enum2, enum3 }; 

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

 // example: ParseEnum("ENUM1", ref eVal); bool ParseEnum(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值?

怎么样的:

 public static class EnumUtils { public static Nullable Parse(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("foo"); 

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

 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(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("Enum11")); Console.WriteLine(ParseEnum("Enum1")); Console.WriteLine(ParseEnum("Enum6").GetType()); Console.WriteLine(ParseEnum("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 . . . 

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

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

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

你会像这样使用它:

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

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

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

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

我刚刚将这里的语法与此处的exception处理结合起来,创建了这个:

 public static class Enum { 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而不是抛出exception。

如果您正在使用.NET 3.5(甚至2.0,如果您删除了扩展方法),我对本文中的技术运气不错:

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

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

https://gist.github.com/1305566

如果要避免使用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 Parse(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; } } 

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

  public static T GetEnum(string s) { Array arr = Enum.GetValues(typeof(T)); foreach (var x in arr) { if (x.ToString().Contains(s)) return (T)x; } return default(T); }