2011-03-04 8 views
11

Solo necesito poder convertir un objeto en una enumeración nulo. Object puede ser enum, null o int. ¡Gracias!objeto de C# cast de tipo int a enum nulo enum

public enum MyEnum { A, B } 
void Put(object value) 
{ 
    System.Nullable<Myenum> val = (System.Nullable<MyEnum>)value; 
} 

Put(null);  // works 
Put(Myenum.B); // works 
Put(1);  // Invalid cast exception!! 
+0

Se ahorrará algunos problemas si utiliza declaraciones fuertemente tipadas. Si sabes que 'Put' espera un' Nullable ', ¿por qué lo declaras con un' objeto'? –

+2

@Ilya Kogan, es una versión simplificada de la función Put, trata de otros tipos de datos, no solo enum – dlsou

Respuesta

33

Cómo sobre: ​​

MyEnum? val = value == null ? (MyEnum?) null : (MyEnum) value; 

El molde de caja int a MyEnum (si value es no nulo) y luego usar la conversión implícita de MyEnum a Nullable<MyEnum>.

Eso está bien, porque puede desmarcar de la forma en caja de una enumeración a su tipo subyacente, o viceversa.

Creo que esto es en realidad una conversión que no se garantiza que funcione por la especificación C#, pero se garantiza para trabajar por la especificación CLI. Así que mientras esté ejecutando su código C# en una implementación de CLI (que será :) estará bien.

+0

Esto funciona, gracias – dlsou

+4

+1 Juro que a diario tomo la guía de una respuesta de Jon Skeet en StackOverflow. Bien hecho señor. – JustinMichaels

+0

Forma más corta: 'MyEnum? val = (MyEnum?) value ?? nulo' – Aesir

11

Esto se debe a que está unboxing y fundición en una sola operación, lo que no está permitido. Solo puede desunir un tipo del mismo tipo que está dentro del objeto.

Para más detalles, recomiendo leer el blog de Eric Lippert: Representation and Identity.

+2

En realidad, no del todo. Ver mi respuesta - usted * puede * unbox desde un 'int' enmarcado a un tipo enum (con 'int' como el tipo subyacente), o desde un valor enum encuadrado a su tipo subyacente. –

+0

@Jon: cierto, pero eso también es un caso marginal (solo funciona porque la "enumeración" es en realidad un "int" en este caso específico) - ¿qué sucede cuando el OP pasa 0.0 en el método? ¿O intentan usar esta técnica con una enumeración respaldada por algo que no sea Int32? Esos aún causarán un problema ... –

+1

Luego se romperá. Pero el OP sí dice: "Object puede ser enum, null o int". En otras palabras, la solución que he dado funciona para el problema tal como se presentó. No sabemos qué comportamiento se desea en otras situaciones. –

1

Cuando asigna un valor a un tipo que admite nulos, debe tener en cuenta que no es el mismo que el tipo subyacente (al menos en este caso). Por lo tanto, para realizar el reparto primero debe desempaquetar:

void Put(object value) 
{ 
    if (value != null) 
    { 
     System.Nullable<Myenum> val = (System.Nullable<MyEnum>)(MyEnum)value; 
    } 
} 
+0

Soy demasiado lento :) – TheBoyan

+0

Esto tampoco funcionará. Este código tiene el mismo error: unboxing y casting en la misma operación. 'Put' debería tener' MyEnum? 'Como parámetro. –

+2

+1 porque * does * work. Aquellos que dicen que no deberían * intentar * it :) –