2012-01-19 16 views
6

Tengo un método que intenta hacer coincidir cadena con el atributo DescriptionAttribute de enum y luego devuelve el valor enum. En caso de que no se encuentra una coincidencia, se debe devolver un valor predeterminado, por lo que pensé que sólo podía volver 0. Pero eso no va a pasar ...Devuelve el valor de Enum predeterminado cuando no se conoce el tipo Enum

private Enum GetEnumFromDescription(Type enumType, string description) 
{ 
     var enumValues = Enum.GetValues(enumType); 

     foreach (Enum e in enumValues) 
     { 
      if (string.Compare(description, GetDescription(e), true) == 0) 
        return e; 
     } 

     return 0; // not compiling 
} 

Cómo debería codificar el anterior?

+0

¿Por qué no pasa el parámetro de tipo usando genéricos? – millimoose

+0

¿Por qué etiquetó esto con "iterator" y "yield-return"? –

+0

@Inerdial ¿Puedo? mi enumType vino de Type.GetReflectionOnlyType (somestringfromdatabase). – Jake

Respuesta

13

Puede utilizar

return (Enum) Activator.CreateInstance(enumType); 

esto le dará el valor predeterminado para el tipo - que es lo que desea.

EDIT: esperaba que supiera el tipo en tiempo de compilación, en cuyo caso los genéricos son un buen enfoque. Aunque parece que ese no es el caso, dejaré el resto de esta respuesta en caso de que sea útil para otra persona.

Como alternativa, se puede usar Unconstrained Melody que ya contiene algo parecido a esta funcionalidad en una forma más eficiente, de tipo seguro :)

MyEnum value; 
if (Enums.TryParseDescription<MyEnum>(description, out value)) 
{ 
    // Parse successful 
} 

value se establecerá en el valor "0" si la operación de análisis ISN no tiene éxito

Actualmente distingue entre mayúsculas y minúsculas, pero puede crear fácilmente una versión que no distinga entre mayúsculas y minúsculas. (O me deja saber y puedo hacerlo.)

+0

'Enum.ToObject (enumType, 0)' debe ser utilizado. – hazzik

+0

@hazzik: * ¿Debería * ser? Porque deberia*? ¿Cuál crees que es la ventaja de eso sobre el enfoque que he sugerido? No estoy diciendo que no funcionará, solo que hay más de una cosa que funcionará, y si vas a decir que alguien * debería * usar un enfoque sobre otro, deberías justificar eso. –

+1

No soy un hablante nativo, y para mí no hay mucha diferencia entre estos verbos modales, lo siento, si ofendí a alguien. Pero, para justificación, creo que es mejor porque 'Activator.CreateInstance' es una solución genérica para _todos los tipos de valor, pero' Enum.ToObject' es específico para enumeraciones. Y también _probably_ funciona más rápido que el activador. Además, 'Enum.ToObject' se usa dentro de' Enum.GetValues ​​(t) ' – hazzik

0

Tal vez esto funcionará

return (Enum)enumValues[0]; 
+2

No, eso no funcionará si la enumeración no define un valor correspondiente a 0. También arrojará una excepción si la enum no 't define * any * valores. –

+1

@JonSkeet hmm ... ¿cómo sabes siquiera los pequeños detalles de la parte superior de tu cabeza? Ciertamente, no es algo que sucede regularmente? – Jake

+0

@Jon No comprendo por qué no funcionaría. Simplemente recupera el primer elemento de la matriz. – clearpath

1

Creo que el enfoque correcto es

(Enum)Enum.ToObject(enumType, 0) 

Debido

  • Activator.CreateInstance es solución genérica para todos los tipos de valor y Enum.ToObject es una solución específica para enumeraciones, por lo Enum.ToObject de Claras intenciones claras del código.
  • Enum.ToObject probablemente funciona más rápido que Activator.CreateInstance
  • Enum.ToObject se utiliza dentro Enum.GetValues para recuperar valores.
Cuestiones relacionadas