2010-04-30 2 views
12

아래와 같이 값 또는 값으로 TryParse 열거 형에 코드를 작성했습니다. Flags 특성을 사용하여 열거 형을 구문 분석하도록이 코드를 확장하려면 어떻게해야합니까?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

: ','문자열을 사용하는 경우 Enum.Parse()이 완벽하게 작동 같은 나머지 나를

HTH 다른 사람

+1

첫 번째 규칙이 null 체크가 아니어야합니까? – ChaosPandion

+0

첫 번째 검사 또는 두 번째는 뭔가가 누락되지 않는 한이 경우 IMO에서 차이를 만들지 않을 것입니다. 왜냐하면 제약 조건이 구조체에 있기 때문에 호출이 유효한 열거 형인지 확인한 후에 값이 맞는지 확인해야한다고 생각합니다. 없는 – Sunny

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

+0

이유는 단지 Enum.Parse과 (WRA)를 사용하지 try/catch 블록 주위에? – yoyo

26

플래그 열거 형은 |을 닷넷 규칙을 사용하지 않음으로써 ,를 사용하여 작성됩니다.

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

나머지 : 팝의 대답은 나에게 내가 규칙처럼 보이도록 내 코드에서 확인 수정 된 단서 &을 준 @

[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