type number convert cast c# c#-4.0 casting boxing unboxing

convert - type number c#



C#- Problemas con boxing/unboxing/typecasting ints. No entiendo (3)

Lo que está pasando es exactamente lo que dice.

En el primer caso, tiene un corto, sin casillero, que está encasillando explícitamente a un int. Esta es una conversión válida que el compilador sabe cómo hacer, por lo que funciona.

En el segundo caso, tiene un int, boxed, que están asignando de nuevo a un int. Este es un simple unboxing de un entero, que también es válido, por lo que funciona.

En el tercer caso, tiene un corto, enmarcado, que está tratando de desagrupar en una variable que no es un corto. Esta no es una operación válida: no puede hacer esto en un solo paso. Este tampoco es un problema poco común: si está utilizando, por ejemplo, un SqlDataReader que contiene una columna SMALLINT , no puede hacer:

int x = (int)rdr["SmallIntColumn"];

Cualquiera de los siguientes debería funcionar en su tercer ejemplo:

object thirdTest = Convert.ToInt16(0); int thirdTest2 = Convert.ToInt32(thirdTest); int thirdTest3 = (int)(short)thirdTest;

Me está costando entender esto. Considere el siguiente ejemplo:

protected void Page_Load(object sender, EventArgs e) { // No surprise that this works Int16 firstTest = Convert.ToInt16(0); int firstTest2 = (int)firstTest; // This also works object secondTest = 0; int secondTest2 = (int)secondTest; // But this fails! object thirdTest = Convert.ToInt16(0); int thirdtest2 = (int)thirdTest; // It blows up on this line. }

El error específico que obtengo en tiempo de ejecución es que el Specified cast is not valid. Si tengo QuickWatch (int)thirdTest en Visual Studio, obtengo un valor de Cannot unbox ''thirdTest'' as a ''int'' .

¿Qué diablos está pasando aquí?


Unboxing comprueba el tipo exacto como se explica en la documentación .

Unboxing es una conversión explícita del tipo de objeto a un tipo de valor o de un tipo de interfaz a un tipo de valor que implementa la interfaz. Una operación de unboxing consiste en:

  • Verificando la instancia del objeto para asegurarse de que sea un valor enmarcado del tipo de valor dado.

  • Copiando el valor de la instancia en la variable de tipo de valor.

Como puede ver, el primer paso es verificar que la instancia del objeto coincida con el tipo de destino.

También cita de la documentación:

Para el desempaquetado de tipos de valor para tener éxito en el tiempo de ejecución, el elemento que se va a desempaquetar debe ser una referencia a un objeto que se creó previamente al encapsular una instancia de ese tipo de valor. El intento de unbox null causa una NullReferenceException. Intentar desempaquetar una referencia a un tipo de valor incompatible causa una InvalidCastException.

Para solucionar este error, asegúrese de que el tipo coincida antes de intentar desagrupar:

object thirdTest = Convert.ToInt16(0); short thirdtest2 = (short)thirdTest;


Int16 es una forma elegante de escribir short ; no hay boxeo / unboxing allí, solo la conversión CLR simple entre enteros de 16 bits y 32 bits.

El segundo caso encajona y unboxes al mismo tipo, que está permitido: value type int se envuelve en un object , y luego se desenvuelve.

El tercer caso intenta unbox a un tipo diferente ( int lugar de short ) que no está permitido.