2010-04-16 12 views
5

He los métodos siguientes en una clase de enumeración helper (He simplificado para el propósito de la pregunta):¿Existe alguna forma mejor de crear una cadena de conversión genérica para el método enum o la extensión enum?

static class EnumHelper 
{ 
    public enum EnumType1 : int 
    { 
     Unknown = 0, 
     Yes = 1, 
     No = 2 
    } 

    public enum EnumType2 : int 
    { 
     Unknown = 0, 
     Dog = 1, 
     Cat = 2, 
     Bird = 3 
    } 

    public enum EnumType3 
    { 
     Unknown, 
     iPhone, 
     Andriod, 
     WindowsPhone7, 
     Palm 
    } 

    public static EnumType1 ConvertToEnumType1(string value) 
    { 
     return (string.IsNullOrEmpty(value)) ? 
      EnumType1.Unknown : 
      (EnumType1)(Enum.Parse(typeof(EnumType1), value, true)); 
    } 

    public static EnumType2 ConvertToEnumType2(string value) 
    { 
     return (string.IsNullOrEmpty(value)) ? 
      EnumType2.Unknown : 
      (EnumType2)(Enum.Parse(typeof(EnumType2), value, true)); 
    } 

    public static EnumType3 ConvertToEnumType3(string value) 
    { 
     return (string.IsNullOrEmpty(value)) ? 
      EnumType3.Unknown : 
      (EnumType3)(Enum.Parse(typeof(EnumType3), value, true)); 
    } 
} 

Así que la pregunta aquí es, ¿puedo recortar esto a un método de extensión de enumeración o tal vez algún tipo de método único que puede manejar cualquier tipo. He encontrado algunos ejemplos para hacerlo con enumeraciones básicas, pero la diferencia en mi ejemplo es que todas las enumeraciones tienen el elemento Unknown que necesito devolver si la cadena es nula o está vacía (si no se encuentra ninguna coincidencia, quiero que falle).

Buscando algo como lo siguiente tal vez:

EnumType1 value = EnumType1.Convert("Yes"); 
// or 
EnumType1 value = EnumHelper.Convert(EnumType1, "Yes"); 

Una función para hacerlo todo ... cómo manejar el elemento Unknown es la parte que me colgó.

Editar: Ajustó una de las enumeraciones para no ser definida con números enteros. Así que puedo garantizar que 0 siempre será el caso, pero Unknown siempre será el texto correcto ... Supongo que podría usar el mismo ejemplo que el T (0) pero hacer otro análisis en el texto "Desconocido".

Respuesta

8

Use esto, suponiendo que Desconocido es siempre el valor 0.

public static T ConvertToEnum<T>(this string value) where T : new() 
{ 
    if(!typeof(T).IsEnum) 
     throw new NotSupportedException("T must be an Enum"); 

    try 
    { 
     return (T)Enum.Parse(typeof(T), value); 
    } 
    catch 
    { 
     return default(T); // equivalent to (T)0 
     //return (T)Enum.Parse(typeof(T), "Unknown")); 
    } 
} 

Uso:

EnumType2 a = "Cat".ConvertToEnum<EnumType2>(); 
EnumType2 b = "Person".ConvertToEnum<EnumType2>(); // Unknown 

EDITAR Por OP (Kelsey): Su respuesta me llevan a la respuesta correcta por lo que pensé que iba a incluirlo aquí:

public static T ConvertTo<T>(this string value) 
{ 
    T returnValue = (T)(Enum.Parse(typeof(T), "Unknown", true)); 
    if ((string.IsNullOrEmpty(value) == false) && 
     (typeof(T).IsEnum)) 
    { 
     try { returnValue = (T)(Enum.Parse(typeof(T), value, true)); } 
     catch { } 
    } 
    return returnValue; 
} 
+1

Restricción no puede ser de clase especial 'System.Enum' –

+0

@ Maud'Dib: Uf, tienes razón. No vi el error en mi proyecto ficticio. Voy a actualizar. – chilltemp

+0

@Kelsey: tienes razón, puedes simplemente rastrear 'Desconocido' cada vez, pero lanzar desde 0 es más eficiente suponiendo que es seguro para tus Enumeraciones. – chilltemp

2

uso de los genéricos ... algo como esto ....

public static TResult ConvertTo<TResult>(this string source) 
{ 
    if(!typeof(TResult).IsEnum) 
    { 
     throw new NotSupportedException("TResult must be an Enum"); 
    } 

    if (!Enum.GetNames(typeof(TResult)).Contains(source)) 
     return default(TResult); 


    return (TResult)Enum.Parse(typeof(TResult), source); 
} 

(the code came from here)

+0

Esto lo sabía cómo hacerlo ... pero ¿cómo recuperaré 'EnumTypeX.Unknown' cuando esté vacío o nulo? – Kelsey

+2

agregue esta línea ... if (! Enum.GetNames (typeof (TResult)). Contiene (fuente)) return default (TResult); –

Cuestiones relacionadas