tl; dr - L' utilisation deChild
overParent
est préférable dans le champ d'application local. Cela facilite non seulement la lisibilité, mais il est également nécessaire de s'assurer que la résolution de la méthode surchargée fonctionne correctement et contribue à une compilation efficace.
Au niveau local,
Parent obj = new Child(); // Works
Child obj = new Child(); // Better
var obj = new Child(); // Best
Conceptuellement, il s’agit de conserver le plus d’informations possibles. Si nous rétrogradons Parent
, nous supprimons essentiellement des informations de type qui auraient pu être utiles.
Conserver les informations de type complètes présente quatre avantages principaux:
- Fournit plus d'informations au compilateur.
- Fournit plus d'informations au lecteur.
- Code plus propre et plus normalisé.
- Rend la logique du programme plus modifiable.
Avantage 1: Plus d'informations au compilateur
Le type apparent est utilisé dans la résolution de méthode surchargée et dans l'optimisation.
Exemple: résolution de méthode surchargée
main()
{
Parent parent = new Child();
foo(parent);
Child child = new Child();
foo(child);
}
foo(Parent arg) { /* ... */ } // More general
foo(Child arg) { /* ... */ } // Case-specific optimizations
Dans l'exemple ci-dessus, les deux foo()
appels fonctionnent , mais dans un cas, nous obtenons la meilleure résolution de méthode surchargée.
Exemple: optimisation du compilateur
main()
{
Parent parent = new Child();
var x = parent.Foo();
Child child = new Child();
var y = child .Foo();
}
class Parent
{
virtual int Foo() { return 1; }
}
class Child : Parent
{
sealed override int Foo() { return 2; }
}
Dans l'exemple ci-dessus, les deux .Foo()
appels appellent finalement la même override
méthode qui renvoie 2
. Dans le premier cas, il existe une recherche de méthode virtuelle pour trouver la méthode correcte; cette recherche de méthode virtuelle n'est pas nécessaire dans le deuxième cas puisque celle-ci est sealed
.
Nous remercions @Ben qui a fourni un exemple similaire dans sa réponse .
Avantage 2: Plus d'informations au lecteur
Connaître le type exact, c.-à-d. Child
, Fournit plus d'informations à quiconque lit le code, ce qui permet de voir plus facilement ce que fait le programme.
Bien sûr, peut - être qu'il n'a pas d' importance au code réel puisque les deux parent.Foo();
et du child.Foo();
sens, mais pour quelqu'un de voir le code pour la première fois, plus d' informations est tout simplement utile.
De plus, en fonction de votre environnement de développement, l'EDI peut être en mesure de fournir plus d'info-bulles et de métadonnées utiles Child
que sur Parent
.
Avantage 3: code plus propre et plus normalisé
La plupart des exemples de code C # que j'ai vus récemment utilisent var
, qui est essentiellement un raccourci pour Child
.
Parent obj = new Child(); // Sub-optimal
Child obj = new Child(); // Optimal, but anti-pattern syntax
var obj = new Child(); // Optimal, clean, patterned syntax "everyone" uses now
Voir une var
déclaration de non- déclaration ne fait que regarder; s'il y a une raison situationnelle pour cela, génial, mais sinon, cela semble anti-modèle.
// Clean:
var foo1 = new Person();
var foo2 = new Job();
var foo3 = new Residence();
// Staggered:
Person foo1 = new Person();
Job foo2 = new Job();
Residence foo3 = new Residence();
Avantage 4: logique de programme plus modifiable pour le prototypage
Les trois premiers avantages étaient les plus importants. celui-ci est beaucoup plus situationnel.
Néanmoins, pour les personnes qui utilisent du code comme d’autres utilisent Excel, nous modifions constamment notre code. Peut-être n’avons-nous pas besoin d’appeler une méthode unique Child
dans cette version du code, mais nous pourrions réutiliser ou reformater le code ultérieurement.
L'avantage d'un système de type fort est qu'il nous fournit certaines méta-données sur la logique de notre programme, rendant ainsi plus évidentes les possibilités. Ceci est incroyablement utile dans le prototypage, il est donc préférable de le conserver lorsque cela est possible.
Sommaire
L'utilisation de la Parent
résolution des méthodes surchargée, empêche certaines optimisations du compilateur, supprime les informations du lecteur et rend le code plus laid.
L'utilisation var
est vraiment la voie à suivre. C'est rapide, propre, modelé, et aide le compilateur et l'IDE à faire leur travail correctement.
Important : Cette réponse concerne environParent
vs.Child
dans la portée locale d'une méthode. La question deParent
vsChild
est très différente pour les types de retour, les arguments et les champs de classe.