2010-04-30 57 views
12

我已经按照如下所示的值或名称将代码写入TryParse enum。如何扩展此代码以包含解析具有Flags属性的枚举?具有标志的Enum.TryParse属性

public static bool TryParse<T>(this T enum_type, object value, out T result) 
       where T : struct 
      { 
       return enum_type.TryParse<T>(value, true, out result); 
      } 



public static bool TryParse<T>(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<T, object, bool, bool>[]{ 
      (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 

谢谢!

回答

0

@流行的回答给了我一个线索&我修改了规则,您在我的代码看起来像:

var is_valid_value_for_conversion = new Func<T, object, bool, bool>[] 
{ 
    (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别人

+1

不应该将空检查作为您的第一条规则吗? – ChaosPandion 2010-04-30 15:49:28

+0

首先检查或第二个在这种情况下不会有所作为IMO,除非我缺少一些东西,除了因为约束在struct上,我认为我们需要检查该调用是否在有效的枚举类型之前检查值是否为空值 – Sunny 2010-04-30 16:20:52

16

从.NET 4开始,有一个Enum.TryParse<T>方法。它支持标志枚举开箱:

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

是在的TryParse 4.0暴露,我一直在寻找在3.5的解决方案...... – Sunny 2010-04-30 15:25:30

+0

为什么不直接使用Enum.Parse和WRA试试/抓住它周围的块? – yoyo 2015-02-18 03:14:50

26

标志枚举使用,使用.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