Enum.TryParse with Flags属性

我已经通过值或其名称为TryParse枚举编写了代码,如下所示。 如何扩展此代码以包含使用Flags属性解析枚举?

  public static bool TryParse(this T enum_type, object value, out T result) where T : struct { return enum_type.TryParse(value, true, out result); } public static bool TryParse(this T enum_type, object value, bool ignoreCase, out T result) where T : struct { result = default(T); var is_converted = false; var is_valid_value_for_conversion = new Func[]{ (e, v, i) => e.GetType().IsEnum, (e, v, i) => v != null, (e, v, i) => Enum.GetNames(e.GetType()).Any(n => String.Compare(n, v.ToString(), i) == 0) || Enum.IsDefined(e.GetType(), v) }; if(is_valid_value_for_conversion.All(rule => rule(enum_type, value, ignoreCase))){ result = (T)Enum.Parse(typeof(T), value.ToString(), ignoreCase); is_converted = true; } return is_converted; } 

目前此代码适用于以下枚举:

 enum SomeEnum{ A, B, C } // can parse either by 'A' or 'a' enum SomeEnum1 : int { A = 1, B = 2, C = 3 } // can parse either by 'A' or 'a' or 1 or "1" 

不适用于:

 [Flags] enum SomeEnum2 { A = 1, B = 2, C = 4 } // can parse either by 'A' or 'a' // cannot parse for A|B 

谢谢!

标志枚举是使用.Net约定而不是|来编写的 。 使用’,’字符串时,Enum.Parse()可以正常工作:

 [Flags] public enum Flags { A = 1, B = 2, C = 4, D = 8, } var enumString = (Flags.A | Flags.B | Flags.C).ToString(); Console.WriteLine(enumString); // Outputs: A, B, C Flags f = (Flags)Enum.Parse(typeof(Flags), enumString); Console.WriteLine(f); // Outputs: A, B, C 

从.NET 4开始,有一个Enum.TryParse 方法。 它支持开箱即用的Flags枚举:

 string x = (SomeEnum2.A | SomeEnum2.B).ToString(); // x == "A, B" SomeEnum2 y; bool success = Enum.TryParse(x, out y); // y == A|B 

@Pop的答案给了我一个线索,我在我的代码中修改了规则检查,如下所示:

 var is_valid_value_for_conversion = new Func[] { (e, v, i) => e.GetType().IsEnum, (e, v, i) => value != null, (e, v, i) => Enum.GetNames(e.GetType()).Any( n => String.Compare(n, v.ToString(), i) == 0 || (v.ToString().Contains(",") && v.ToString().ToLower().Contains(n.ToLower()))) || Enum.IsDefined(e.GetType(), v) }; 

其余的保持不变,它适用于我

HTH别人