2010-10-12 25 views
7

Me encontré con un problema hoy y no estaba del todo seguro de por qué no funcionaría.Tipo de objeto de fundición en C#

El siguiente ejemplo de código se colgará:

static void Main(string[] args) 
{ 
    int i32 = 10; 
    object obj = i32; 
    long i64 = (long)obj; 
} 

Esto dará lugar a un InvalidCastException. ¿Por qué esto no funciona? ¿C# no es lo suficientemente inteligente como para saber que el objeto es en realidad de tipo int?

Ya he encontrado una solución alternativa, pero tengo curiosidad de por qué el ejemplo de código anterior no funcionó en primer lugar.

Gracias, Tim

+1

Observo que este es un duplicado de muchas preguntas anteriores, incluyendo la más reciente http://stackoverflow.com/questions/3911293 –

Respuesta

9

No hay reparto disponible de una caja a Int32 Int64. Cómo hacer una fundición intermedia a int debería funcionar, porque el compilador está dispuesto para generar esto:

// verify obj is a boxed int, unbox it, and perform the *statically* 
// known steps necessary to convert an int to a long 
long i64 = (long) ((int)obj); 

pero no (hipotéticamente) esto:

// Find out what type obj *actually* is at run-time and perform 
// the-known-only-at-run-time steps necessary to produce 
// a long from it, involving *type-specific* IL instructions 
long i64 = (long)obj; 

He aquí una blog post por Eric Lippert sobre esto.

1

¿Quiere decir el compilador o el tiempo de ejecución?

El tiempo de ejecución es lo suficientemente inteligente, por lo que arroja el InvalidCastException. Sin embargo, el compilador no puede saber con certeza de qué tipo es su objeto, ya que encasilló su int.

El boxeo y el desempaquetado permiten que los tipos de valor sean tratados como objetos. Encajonar un tipo de valor lo empaqueta dentro de una instancia del tipo Referencia de objeto .

Así que, puesto que está encasillado como un objeto, el compilador no se quejará de ello.

ver más información sobre el boxeo y unboxing aquí:

http://msdn.microsoft.com/en-us/library/yz2be5wk%28VS.80%29.aspx

3

Salida this blog post por Eric Lippert para los detalles morbosos.

La esencia de esto es que sería muy lento para el compilador averiguar (por prueba y error, ya que object puede ser cualquier cosa) qué tipo ha sido encuadrado y si puede o no ser lanzado con seguridad.

Cuestiones relacionadas