2010-04-30 15 views
12

He escrito el código en TryParse enum ya sea por valor o por su nombre como se muestra a continuación. ¿Cómo puedo extender este código para incluir enumeraciones de análisis con el atributo Flags?Enum.TryParse con el atributo 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; 
    } 

Actualmente este código funciona para las siguientes enumeraciones:

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" 

no funciona para:

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

Gracias!

Respuesta

0

@ respuesta de papá me dio una pista & he modificado revisar las reglas en mi código para parecerse a:

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

el resto sigue siendo el mismo y funciona para mí

HTH otra persona

+1

¿No debería ser la primera regla la verificación nula? – ChaosPandion

+0

El primer cheque o segundo no marcaría la diferencia en este caso IMO, a menos que me falta algo, además porque la restricción está en struct, creo que necesitamos verificar si la llamada está en un tipo de enumeración válido antes de verificar si el valor es nulo – Sunny

16

A partir de .NET 4, hay un método Enum.TryParse<T>. Es compatible con Banderas enumeraciones de la caja:

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

sí TryParse está expuesto en 4.0, que estaba buscando una solución en 3,5 ... – Sunny

+0

¿por qué no sólo tiene que utilizar Enum.Parse y WRA ¿un bloque de prueba/captura a su alrededor? – yoyo

26

Banderas enumeraciones se escriben utilizando , mediante el uso de la convención .Net y no |. Enum.Parse() funciona perfectamente cuando se utiliza '' cadenas:

[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 
Cuestiones relacionadas