Tipo de error fundición y constructor
-
01-10-2019 - |
Pregunta
Tengo dos clases
public class A
{
public A()
{
}
}
public class B:A
{
public B()
{
}
}
y el código principal es el siguiente
A oa = new B();
B ob = new A();
Aquí la línea 1 compila correctamente mientras que la línea 2 muestra error Encasillamiento. ¿Por qué sucede esto. ¿Qué ocurre exactamente cuando new B()
y new A()
es llamado?
Solución
¿Qué ocurre exactamente cuando nuevo B () y Una nueva () se llama?
-
new A()
construye un objeto de tipoA
en el montón y devuelve una referencia a la misma. -
new B()
construye un objeto de tipoB
en el montón y devuelve una referencia a la misma.
A continuación, la línea 1 se compila correctamente mientras que la línea 2 muestra typecasting error. ¿Por qué sucede esto.
Desde subclases B
A
, es válido para una referencia de tipo A
para referirse a un objeto de tipo B
de tiempo de ejecución. Después de todo, B
es simplemente un "caso especial" de A
.
Sin embargo, lo contrario no es cierto, porque no todos los A
s pueden considerarse B
s.
Aunque esto se aplica estrictamente por C # 's seguro tipo de sistema, incluso si no hay incompatibilidad 'real', las razones de dichas restricciones son naturales. Imagínese, por ejemplo, que B
declarada public int Foo {get; set;}
propiedad.
¿Cómo se puede esperar que esto comporta:
B ob = new A();
ob.Foo = 5;
Esto es claramente ilógico: el real objeto de que la referencia se refiere a no tiene tal propiedad. En consecuencia, el compilador prohíbe tales constructos.
Ahora imagina que cambiado el código a:
B b = (B)new A();
A continuación, le está diciendo al compilador que el objeto creado, será, en en tiempo de ejecución , podrá asignar a una referencia de tipo B
. Esto compilará bien, pero ya que la afirmación es claramente incorrecta, será lanzado un InvalidCastException
en tiempo de ejecución.
En resumen, el sistema de tipo C # 's (si se ignora dynamic
y algunos casos especiales) es a la vez estática y seguro : usted no será éxito capaz de tratar un concreto instancia de A
como si se tratara de tipo B
.
Otros consejos
Se han declarado una variable de tipo B
y, a continuación, intento de asignar un valor de tipo A
a ella. Ha definido B
a ser una especie de A
, pero eso no quiere decir que todos son de A
B
de.
Piense en ello como esto:
class Animal { }
class Dog : Animal { }
class Cat : Animal { }
Se puede hacer Animal rex = new Dog()
, porque todos los perros son los animales, pero no Dog fido = new Animal()
, porque no todos los animales son perros.