2010-10-13 10 views
9

Ok Debo pasar por alto algo extremadamente simple pero estoy perdido.Confundido por el boxeo. Casting -1 a Int64 throws InvalidCastException

Dada esta

object val = -1; 
var foo = (Int32)(val); 
var bar = (Int64)(val); 

El reparto a Int64 tiros y InvalidCastException.

Reconozco que esto está relacionado con algunas rarezas con el boxeo, pero no entiendo el razonamiento.

Por lo que entiendo, val está encasillado como Int32 en la primera línea.

Luego, cuando intento lanzar como algo que no sea Int32 se lanza InvalidCastException. Supongo que esto significa que estoy tratando de unbox val como Int64 cuando en realidad es un Int32?

Parece extraño. ¿No pudo el reparto unbox el valor y luego tratar de realizar el reparto?

Algo así como (Obviamente, esto es terriblemente simplista, tal vez el tipo de caja no se sabe lo que esto no es posible?):

object val = -1; 
Int32 unboxed = (Int32)(val); 
var bar = (Int64)(unboxed); 

Alguien (léase: Eric Lippert) Escuela de mí en el razonamiento detrás de esta.

ACTUALIZACIÓN: Del Blog de Eric Reed que publicó un enlace a esta es la respuesta sucinta que estaba buscando

" ... Esto sería una gran cantidad de código para generar, y sería El código es, por supuesto, tan grande que le gustaría ponerlo en su propio método y simplemente generar una llamada a él. En lugar de hacerlo por defecto, y siempre generar código que es lento, grande y frágil, en su lugar hemos decidido que el desempaquetado solo puede desunir al tipo exacto. Si desea llamar al método lento que hace todo eso, está disponible; siempre puede llamar a Convert.ToInt32, que hace todo ese análisis en tiempo de ejecución para ti. Le damos la opción entre "rápido y preciso" o "lento y laxo", y el valor predeterminado es el primero. Si desea lo último, llame al método ... "

+0

esto es algo. extremadamente no sim ple. Desplaza a mucha gente ... –

+0

Reed tiene razón; esto se hace varias veces a la semana en SO. Fue preguntado dos veces ayer. –

+0

Entonces, soy claramente cobarde por hacer la misma pregunta que todos los demás y no buscar primero. Me parece interesante que esto todavía obtenga 6 votos si es una pregunta tan común. Aparentemente, el comportamiento predeterminado no es el comportamiento más obvio. –

Respuesta

15

Esto se debe a que no puede deshacer la caja y realizar una conversión en una sola operación. Debe desempaquetar el valor Int32 en un Int32 y luego convertir . su tipo

Debido a eso, esto requiere que el objeto que se sacó de la caja, luego se convierte en Int64:

object val = -1; 
int foo = (Int32)val; 
Int64 bar = (Int64)(Int32)val; 

Eric Lippert cubierto esto en detalle en su post titulado Representation and Identity

+0

Impresionante, Eric Lippert por proxy :) Rock –

+0

Otra forma de escribir: 'Int64 a = -1; objeto o = a; Int64 b = (Int64) o; '¡Gracias Reed! – Nayan

+0

¿Podrían las personas dejar de decir * emitir * cuando quieren decir * conversión *? No hay "conversión" entre tipos enteros; están siendo * convertidos *.(Es desafortunado que C# utiliza la misma sintaxis para ambos.) – Timwi

Cuestiones relacionadas