Pregunta

Considere el siguiente ::

Object box = 5;
int @int = (int)box;  // int = 5
int? nullableInt = box as int?; // nullableInt = 5;
StringComparison @enum = (StringComparison)box; // enum = OrdinalIgnoreCase
StringComparison? nullableEnum = box as StringComparison?; // nullableEnum = null.

2 cosas ::

  1. ¿Por qué puedo desempacar a StringComparison? Supongo que esto se debe a que es el tipo subyacente se Int32 pero todavía me resulta extraño.
  2. ¿Por qué nullableEnum tiene un valor de null?

A mi entender el unboxing solamente válido es de un tipo de valor en caja es a su tipo o de un tipo anulable. Si int puede desempacar a Enum, entonces ¿por qué no hace lo mismo es cierto para los valores anulables? Del mismo modo, si en lugar de 5 I StringComparison.OrdinalIgnoreCase en caja, sería que nullableInt sería nula, pero no sería nullableEnum.

¿Fue útil?

Solución

En sentido estricto Creo que es un error en detalle de implementación de el tiempo de ejecución, ya que la especificación C # dice

  

Unboxing a un tipo anulable produce el valor nulo de la de tipo anulable si la fuente operando es nulo, o el resultado envuelto de unboxing la instancia del objeto al tipo subyacente de la de tipo anulable lo contrario.

Es decir, si unboxing a StringComparison funciona, entonces unboxing a anulable debería funcionar también. Es un poco claro si ambos deben trabajar o ambos deben fallar. La especificación dice que

  

Para una conversión unboxing a una de tipo no anulable-valor dado para tener éxito en tiempo de ejecución, el valor de la fuente de operando debe ser una referencia a un valor en caja de que la no-de tipo valor anulable.

Usted tiene que decidir si un int en caja es un considerado como un valor en caja de tipo StringComparison porque el tipo subyacente de StringComparison es int. La especificación continúa diciendo que un InvalidCastException se produce si la caja contiene un "objeto incompatibles". Un int es ciertamente "compatible" con StringComparison, porque se puede copiar de forma segura los cuatro bytes de la pila en su variable de StringComparison.

Otros consejos

Cuando lanzas enumeración o entero a objeto, que sigue siendo válida la información de tipo. Así box is StringComparison volverá false. Pero se le permite lanzar cualquier enumeración o int a cualquier enumeración, por lo que las obras (StringComparison)box conversión explícita. Es un caso especial para las enumeraciones. Nullable<T>, por el contrario, es sólo una clase habitual, T no es manejado de ninguna manera específica cuando lanzas o escribe el cheque. Es por esto que este código arrojará una excepción.

        StringComparison? nullableEnum = (StringComparison?)nullableInt;

1) Sí, el tipo de enumeración subyacente es de tipo int y que de por qué funciona de esta manera. Aún más. Puede hacer lo siguiente:

enum MyEnum
{
    One = 1,
    Two = 2,
}

int i = 3;
MyEnum myEnum = (MyEnum)i; // This works without exceptions.

2) Debido a StringComparison? es en realidad Nullable<StringComparison> que es de tipo diferente. Y operador as sólo comprueba si el objeto es del mismo tipo como se especifica en como operador.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top