2010-07-15 17 views
37

Estoy escribiendo una función de utilidad que obtiene un número entero de la base de datos y devuelve un enum escrito a la aplicación.¿Puedo transmitir de un tipo genérico a una enumeración en C#?

Esto es lo que he intentado hacer (nótese que pase en un nombre de lector de datos y la columna en lugar de la int en mi función real):

public static T GetEnum<T>(int enumAsInt) 
{ 
    Type enumType = typeof(T); 

    Enum value = (Enum)Enum.ToObject(enumType, enumAsInt); 
    if (Enum.IsDefined(enumType, value) == false) 
    { 
     throw new NotSupportedException("Unable to convert value from database to the type: " + enumType.ToString()); 
    } 

    return (T)value; 
} 

Pero no me deja echo (T)value diciendo:

No se puede convertir el tipo 'System.Enum' a 'T'.

También he leído bastantes críticas contradictorias sobre el uso de Enum.IsDefined. En cuanto a rendimiento, suena muy pobre. ¿De qué otra manera puedo garantizar un valor válido?

+0

Tenga en cuenta que si el caso había sido Por otro lado, por ejemplo, tienes que hacer '(Enum) v alue' y obtienes 'No se puede convertir el tipo 'T' a 'System.Enum'', simplemente podrías hacer un molde' as', como' value como Enum'. – nawfal

+1

No es cierto (al menos en mi caso), obtienes el antiguo 'El operador as se debe usar con un tipo de referencia o nulo (el tipo' Foo.bar 'es un tipo de valor que no admite nulos). – keithl8041

Respuesta

58

De esta manera:

return (T)(object)value; 
+3

Sería mejor declarar inicialmente 'value' como' object'. –

+0

Gracias que parece compilar. No entiendo la razón del error, entonces? Puntos de bonificación si puede explicar por qué con el interés de aprender :) – Justin

+2

El compilador no se da cuenta de que 'T' es un tipo enum. Por lo que sabe, 'T' podría ser' DateTime'. Por lo tanto, no puedes convertir directamente de cualquier tipo que no sea 'object' a' T'. – SLaks

11

cambiar esta situación:

Enum value = (Enum)Enum.ToObject(enumType, enumAsInt); 

a esto:

T value = (T)Enum.ToObject(enumType, enumAsInt); 

y retirar el molde :)

Cuestiones relacionadas