2009-12-06 13 views
6

Estoy escribiendo una función que toma un Enum y lo lanza al uint. Por lo que he visto al convertir a int, primero debes convertirlo en un objeto: (int) (object) myEnumValue. Si escribe (int) myEnumValue, obtendrá una excepción de tiempo de compilación.Casting Enum to uint

Ahora, cuando traté de lanzarlo a uint, esperaba que (uint) (object) myEnumValue estaría bien. Se compila muy bien, pero cuando se ejecuta genera un InvalidCastException. Así que para conseguir que funcione, he utilizado

(uint) (int) (object) myEnumValue 

Creo que se ve divertido, así que estoy muy feliz, pero ¿por qué es así?

quizás hubiera sido más correcto para preguntar por qué no es posible lanzar object a uint, pero estoy interesado en saber si hay otra manera de pasar de una a Enumuint. ¿Esta ahí?

Editar:

El contexto es una función, algo como esto:

public static uint ToUInt (Enum e) 
{ 
    return (uint) (int) (object) e; 
} 

Edición 2:

La mejor solución fue como se ha mencionado por thecoop:

Convert.ToUInt32(e) 

Respuesta

13

El enfoque (uint) (object) myEnum falla porque, de manera predeterminada, las enumeraciones de C# usan int como su tipo subyacente, y int es lo que se convierte cuando se encuadran. La sintaxis de C# hace que parezca que las enumeraciones heredan de su tipo subyacente (como enum MyEnum : uint).

Hay que indicar explícitamente al compilador para desempacar de object a int primero, y luego hacer una conversión numérica de int a uint. (A pesar de que la sintaxis es la misma, unboxing de object a un tipo de valor es un proceso diferente de fundición entre int y uint.)

+0

Ok, entonces si especifico mi Enum como Enum: uint, ¿sería al revés? –

+0

@Jonatan: sí, eso encajonaría la enumeración como una uy, y se vería obligado a desagrupar como lo hace. –

+0

Correcto: (uint) e estará bien, pero (int) e explotará. –

5

Por lo que he visto cuando se lanza a int, hay que echarlo a un objeto primero: (int) (object) myEnum. Si escribe (int) myEnum, obtendrá una excepción de tiempo de compilación.

No es cierto. Puedes convertir directamente un valor enum a un tipo entero.

Ahora, cuando traté de convertirlo en uint, estaba esperando que (uint) (object) myEnum estuviera bien. Se compila muy bien, pero cuando se ejecuta, genera una InvalidCastException. Para que funcione, he usado: (uint) (int) (object) myEnum
Creo que se ve raro, así que estoy bastante contento, pero ¿por qué?

Cuando lanzas un valor de enumeración a object, que va a ser en caja como su subyacente tipo, que es int por defecto.No puede desvincular un valor en caja a ningún tipo que no sea el tipo real directamente. Incluso esta fallará:

short s = 10; 
object o = s; 
int i = (int)o; // throws `InvalidCastException` while `int i = (int)s;` works. 
0

En caso de tener que ir en la dirección opuesta, es decir, de un tipo subyacente a la enumeración de un tipo particular:

enum MyEnumType { a, b, c }; 
//... 
MyEnumType enum_val = (MyEnumType)Enum.ToObject(typeof(MyEnumType), 2); 
Console.WriteLine(enum_val == MyEnumType.c); 
// "True" 

He encontrado que esto es necesario (en lugar de simple conversión) al crear tipos genéricos. Dado que no puede usar las cláusulas 'where' para restringir suficientemente el < genérico 0 > a su tipo de enumeración, el compilador no le permitirá convertirlo en un número.