Me gustaría crear un método genérico para convertir cualquier tipo derivado de System.Enum a su valor entero correspondiente, sin conversión y preferiblemente sin analizar una cadena.
Por ejemplo, lo que quiero es algo como esto:
// Trivial example, not actually what I'm doing.
class Converter
{
int ToInteger(System.Enum anEnum)
{
(int)anEnum;
}
}
Pero esto no parece funcionar. Resharper informa que no puede convertir una expresión de tipo 'System.Enum' a escribir 'int'.
Ahora se me ocurrió esta solución, pero prefiero tener algo más eficiente.
class Converter
{
int ToInteger(System.Enum anEnum)
{
return int.Parse(anEnum.ToString("d"));
}
}
¿Alguna sugerencia?
c#
enums
type-conversion
orj
fuente
fuente
Respuestas:
Si no quieres emitir,
podría hacer el truco.
La transmisión directa (vía
(int)enumValue
) no es posible. Tenga en cuenta que esto también sería "peligroso", ya que una enumeración puede tener diferentes tipos subyacentes (int
,long
,byte
...).Más formalmente:
System.Enum
no tiene una relación de herencia directa conInt32
(aunque ambos sonValueType
s), por lo que la conversión explícita no puede ser correcta dentro del sistema de tiposfuente
Converter.ToInteger(MyEnum.MyEnumConstant);
no le dará ningún error aquí. Edite esa parte.int
long
enum.System.Enum
es una clase, por lo que es un tipo de referencia. Los valores probablemente estén encuadrados.Lo hice funcionar lanzando a un objeto y luego a un int:
Esta es fea y probablemente no sea la mejor manera. Seguiré jugando con eso, para ver si puedo encontrar algo mejor ...
EDITAR: Estaba a punto de publicar que Convert.ToInt32 (enumValue) también funciona, y noté que MartinStettner se me adelantó.
Prueba:
EDITAR 2: En los comentarios, alguien dijo que esto solo funciona en C # 3.0. Acabo de probar esto en VS2005 así y funcionó:
fuente
Si necesita convertir cualquier enumeración a su tipo subyacente (no todas las enumeraciones están respaldadas por
int
), puede usar:fuente
Convert.ChangeType
aceptaobject
el primer argumento y regresaobject
.¿Por qué necesitas reinventar la rueda con un método auxiliar? Es perfectamente legal asignar un
enum
valor a su tipo subyacente.Es menos mecanografiado y, en mi opinión, más legible de usar ...
... en lugar de algo como ...
fuente
De mi respuesta aquí :
Dado
e
como en:Entonces estos funcionan:
Los dos últimos son feos. El primero debería ser más legible, aunque el segundo es mucho más rápido. O puede ser que un método de extensión sea lo mejor, lo mejor de ambos mundos.
Ahora puedes llamar:
fuente
e
variable ya tiene la instancia en caja del tipo de valor real, es decir, enum. Cuando escribeEnum e = Question.Role;
, ya está en una caja. La pregunta es sobre convertir el recuadroSystem.Enum
en el tipo int subyacente (unboxing). Así que aquí el desembalaje es solo una cuestión de rendimiento.(int)(object)e
es una llamada directa de unbox; sí debería ser más rápido que otros enfoques. Ver estoTransmitir de una
System.Enum
a unaint
funciona bien para mí (también está en MSDN ). Quizás sea un error de Resharper.fuente
System.Enum
, no élSystem.Enum
mismo.Dado que las enumeraciones están restringidas a byte, sbyte, short, ushort, int, uint, long y ulong, podemos hacer algunas suposiciones.
Podemos evitar excepciones durante la conversión utilizando el contenedor más grande disponible. Desafortunadamente, no está claro qué contenedor usar porque ulong aumentará para números negativos y long aumentará para números entre long.MaxValue y ulong.MaxValue. Necesitamos cambiar entre estas opciones según el tipo subyacente.
Por supuesto, aún debe decidir qué hacer cuando el resultado no encaja dentro de un int. Creo que el casting está bien, pero todavía hay algunos errores:
Aquí está mi sugerencia, dejaré que el lector decida dónde exponer esta función; como ayudante o extensión.
fuente
No olvide que el tipo Enum en sí tiene un montón de funciones auxiliares estáticas. Si todo lo que quiere hacer es convertir una instancia de la enumeración a su tipo entero correspondiente, entonces la conversión es probablemente la forma más eficiente.
Creo que ReSharper se queja porque Enum no es una enumeración de ningún tipo en particular, y las enumeraciones en sí se derivan de un tipo de valor escalar, no de Enum. Si necesita una conversión adaptable de una manera genérica, diría que esto podría adaptarse bien a usted (tenga en cuenta que el tipo de enumeración en sí también se incluye en el genérico:
Esto podría usarse así:
No puedo decirlo con certeza, pero el código anterior incluso podría ser compatible con la inferencia de tipo de C #, lo que permite lo siguiente:
fuente
EnumHelpers.Convert<int, StopLight>(StopLight.Red);
lugar de(int)StopLight.Read;
? También se habla de la preguntaSystem.Enum
.