2010-04-30 58 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