Tiempo de comstackción y tiempo de ejecución c #

Me preguntaba por qué algunos modelos en C # se controlan en tiempo de comstackción, mientras que en otros casos la responsabilidad recae en CLR. Al igual que arriba, ambos son incorrectos pero se manejan de una manera diferente.

class Base { } class Derived : Base { } class Other { } static void Main(string[] args) { Derived d = (Derived)new Base(); //Runtime InvalidCastException Derived d = (Derived)new Other(); //Compile-time Cannot convert type... } 

Mientras leía “C # en profundidad” , encontré la información sobre este tema donde el autor dice:
“Si el comstackdor detecta que en realidad es imposible que funcione ese lanzamiento, desencadenará un error de comstackción, y si está teóricamente permitido pero realmente incorrecto en el momento de la ejecución, el CLR arrojará una excepción”.

¿Significa ‘teóricamente’ estar conectado por jerarquía de herencia (alguna otra afinidad entre objetos?) O es el negocio interno del comstackdor?

  • Las actualizaciones se pueden verificar en tiempo de comstackción: el sistema de tipos garantiza que el reparto tiene éxito.
  • Los downcasts no pueden (en general) verificarse en tiempo de comstackción, por lo que siempre se verifican en tiempo de ejecución.
  • Los tipos no relacionados no se pueden lanzar el uno al otro.

El comstackdor considera solo los tipos estáticos. El tiempo de ejecución comprueba el tipo dynamic (tiempo de ejecución). Mirando tus ejemplos:

 Other x = new Other(); Derived d = (Derived)x; 

El tipo estático de x es Other . Esto no está relacionado con Derived por lo que el lanzamiento falla en tiempo de comstackción.

 Base x = new Base(); Derived d = (Derived)x; 

El tipo estático de x ahora es Base . Algo de tipo Base podría tener un tipo dynamic Derived , por lo que este es un abatimiento. En general, el comstackdor no puede saber del tipo estático de x si el tipo de tiempo de ejecución es Base , Derived , de alguna otra subclase de Base . Entonces, la decisión de si el elenco está permitido se deja al tiempo de ejecución.

Si su variable es de tipo Base , se puede construir teóricamente mediante el constructor Derived , siendo así una variable de tipo Derived realmente. En tiempo de comstackción, el comstackdor no se molesta en tratar de averiguar si en cada caso particular es posible una bajada (que representa una variable del tipo Base como una entidad del tipo Derived ).

Tu muestra es simple: creas una nueva clase y la lanzas de inmediato. Pero, ¿y si obtienes Base desde otro lugar, por ejemplo, alguna llamada a un método? El comstackdor simplemente no puede “adivinar” cuál es el método que va a devolver y, por lo tanto, arrojar no arrojar un error.

Cuando lanzas Other , el comstackdor ve que no hay posibilidad de que Other sea ​​realmente Derived y arroja una excepción.