Tapez erreur coulée et constructeur
-
01-10-2019 - |
Question
J'ai deux classes
public class A
{
public A()
{
}
}
public class B:A
{
public B()
{
}
}
et le code principal est comme suit
A oa = new B();
B ob = new A();
1 ligne ici compiles avec succès tandis que la ligne 2 affiche une erreur transtypage. Pourquoi cela se produit. Que se passe exactement quand new B()
et new A()
est appelé?
La solution
Qu'est-ce qui se passe exactement lorsque le nouveau B () et A nouveau () est appelée?
-
new A()
construit un objet de typeA
sur le tas et renvoie une référence. -
new B()
construit un objet de typeB
sur le tas et renvoie une référence.
ligne ici 1 compiles avec succès tandis que la ligne 2 affiche transtypage Erreur. Pourquoi cela se produit.
Depuis les sous-classes de B
A
, il est valable pour une référence de type A
pour désigner un objet de B
type d'exécution. Après tout, B
est tout simplement un « cas particulier » de A
.
Cependant, l'inverse est pas vrai, car tous les A
s peuvent être considérés comme B
s.
Bien que cela soit strictement appliquée par C # de sécurité système de type, même s'il n'y a pas d'incompatibilité « réelle », les raisons de ces restrictions sont naturelles. Imaginez, par exemple, que B
a déclaré un public int Foo {get; set;}
de propriété.
Comment voulez-vous attendre à ce que se comporter:
B ob = new A();
ob.Foo = 5;
Ceci est clairement illogique: real objet que la référence fait référence à n'a pas une telle propriété. Par conséquent, le compilateur interdit de telles constructions.
Maintenant, imaginez que vous avez changé votre code:
B b = (B)new A();
Ici, vous dites au compilateur que l'objet créé, sera, à run-time , cessible à une référence de type B
. Cela va compiler bien, mais étant donné que l'affirmation est manifestement erronée, un InvalidCastException
d'exécution sera lancée.
En résumé, le système de type de C # (si vous ignorez dynamic
et quelques cas particuliers) est à la fois statique et sécurité : vous serez pas avec succès en mesure de traiter un béton instance de A
comme si elle était de type B
.
Autres conseils
Vous avez déclaré une variable de type B
, puis tenté d'attribuer une valeur de type A
à elle. Vous avez défini B
être une sorte de A
, mais cela ne veut pas dire que tout est de A
sont B
de.
Pensez comme ceci:
class Animal { }
class Dog : Animal { }
class Cat : Animal { }
Vous pouvez faire Animal rex = new Dog()
, parce que tous les chiens sont des animaux, mais pas Dog fido = new Animal()
, car tous les animaux sont des chiens.