2010-04-30 5 views
12

Я набрал код TryParse перечисление либо по значению, либо по его названию, как показано ниже. Как я могу расширить этот код, включив в него синтаксический анализ с атрибутом Flags?Enum.TryParse с атрибутом Flags

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

остальное оставаясь такой же, и это работает для меня

НТН кто-то

+1

Должно ли не первое подтверждение быть первым правилом? – ChaosPandion

+0

Первая проверка или вторая не повлияет на IMO в этом случае, если я не пропущу что-либо, кроме того, поскольку ограничение связано с struct, я думаю, нам нужно проверить, действительно ли вызов имеет действительный тип перечисления, прежде чем проверять, является ли это значение ноль – 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 p блок try/catch вокруг него? – yoyo

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 
Смежные вопросы