tl; dr - Die Verwendung vonChild
overParent
ist im lokalen Bereich vorzuziehen. Dies trägt nicht nur zur Lesbarkeit bei, sondern auch dazu, dass die überladene Methodenauflösung ordnungsgemäß funktioniert und eine effiziente Kompilierung ermöglicht.
Im lokalen Bereich,
Parent obj = new Child(); // Works
Child obj = new Child(); // Better
var obj = new Child(); // Best
Konzeptionell geht es darum, die bestmöglichen Typinformationen zu erhalten. Wenn wir auf downgraden Parent
, streichen wir im Wesentlichen nur Typinformationen heraus, die nützlich gewesen sein könnten.
Das Beibehalten der vollständigen Typinformationen hat vier Hauptvorteile:
- Stellt dem Compiler weitere Informationen zur Verfügung.
- Bietet dem Leser weitere Informationen.
- Sauberer, standardisierter Code.
- Macht die Programmlogik veränderlicher.
Vorteil 1: Mehr Informationen zum Compiler
Der scheinbare Typ wird bei überladener Methodenauflösung und bei der Optimierung verwendet.
Beispiel: Überladene Methodenauflösung
main()
{
Parent parent = new Child();
foo(parent);
Child child = new Child();
foo(child);
}
foo(Parent arg) { /* ... */ } // More general
foo(Child arg) { /* ... */ } // Case-specific optimizations
Im obigen Beispiel funktionieren beide foo()
Aufrufe , aber in einem Fall erhalten wir die bessere Auflösung für überladene Methoden.
Beispiel: Compileroptimierung
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; }
}
Im obigen Beispiel .Foo()
rufen beide Aufrufe letztendlich dieselbe zurückgegebene override
Methode auf 2
. Im ersten Fall gibt es eine virtuelle Methodensuche, um die richtige Methode zu finden. Diese Suche nach virtuellen Methoden ist im zweiten Fall nicht erforderlich, da diese Methoden vorhanden sind sealed
.
Dank an @Ben, der in seiner Antwort ein ähnliches Beispiel lieferte .
Vorteil 2: Mehr Informationen für den Leser
Wenn Sie den genauen Typ kennen, dh wissen Child
, wer den Code liest, erhalten Sie mehr Informationen, damit Sie besser sehen können, was das Programm tut.
Sicher, vielleicht ist es für den eigentlichen Code nicht wichtig, da beide parent.Foo();
und child.Foo();
Sinn machen, aber für jemanden, der den Code zum ersten Mal sieht, sind mehr Informationen einfach nur hilfreich.
Abhängig von Ihrer Entwicklungsumgebung kann die IDE möglicherweise hilfreichere QuickInfos und Metadaten bereitstellen Child
als Parent
.
Vorteil 3: Saubererer, standardisierterer Code
Die meisten C # -Codebeispiele, die ich in letzter Zeit gesehen habe, verwenden var
diese Abkürzung 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
Das Anzeigen einer nicht var
deklarationspflichtigen Anweisung sieht einfach nicht so aus. Wenn es einen situationsbedingten Grund dafür gibt, ist es großartig, aber ansonsten sieht es nicht nach Muster aus.
// 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();
Vorteil 4: Mehr veränderbare Programmlogik für das Prototyping
Die ersten drei Vorteile waren die großen; Das hier ist weitaus situativer.
Für Leute, die Code wie andere verwenden, die Excel verwenden, ändern wir jedoch ständig unseren Code. Möglicherweise müssen wir keine Methode aufrufen, die Child
in dieser Version des Codes eindeutig ist , aber wir können den Code später erneut verwenden oder überarbeiten.
Der Vorteil eines starken Typsystems besteht darin, dass es uns bestimmte Metadaten über unsere Programmlogik liefert, wodurch die Möglichkeiten leichter ersichtlich werden. Dies ist beim Prototyping unglaublich nützlich, daher ist es am besten, es so weit wie möglich beizubehalten.
Zusammenfassung
Wenn Sie Parent
die überladene Methodenauflösung durcheinander bringen, werden einige Compiler-Optimierungen verhindert, Informationen aus dem Reader entfernt und der Code wird hässlicher.
Verwenden var
ist wirklich der richtige Weg. Es ist schnell, sauber, strukturiert und hilft dem Compiler und der IDE, ihre Arbeit richtig zu machen.
Wichtig : Diese Antwort bezieht sich aufParent
vs.Child
im lokalen Bereich einer Methode. Das Problem vonParent
vs.Child
ist für Rückgabetypen, Argumente und Klassenfelder sehr unterschiedlich.