tl; dr - è preferibile utilizzare Child
su Parent
nell'ambito locale. Non solo aiuta con la leggibilità, ma è anche necessario assicurarsi che la risoluzione del metodo sovraccarico funzioni correttamente e aiuti a rendere efficiente la compilazione.
Nell'ambito locale,
Parent obj = new Child(); // Works
Child obj = new Child(); // Better
var obj = new Child(); // Best
Concettualmente, si tratta di mantenere la maggior parte delle informazioni di tipo possibili. Se eseguiamo il downgrade a Parent
, stiamo essenzialmente eliminando le informazioni sul tipo che avrebbero potuto essere utili.
Mantenere le informazioni complete sul tipo ha quattro vantaggi principali:
- Fornisce ulteriori informazioni al compilatore.
- Fornisce ulteriori informazioni al lettore.
- Pulitore, codice più standardizzato.
- Rende la logica del programma più mutevole.
Vantaggio 1: ulteriori informazioni sul compilatore
Il tipo apparente viene utilizzato nella risoluzione del metodo sovraccarico e nell'ottimizzazione.
Esempio: risoluzione del metodo di overload
main()
{
Parent parent = new Child();
foo(parent);
Child child = new Child();
foo(child);
}
foo(Parent arg) { /* ... */ } // More general
foo(Child arg) { /* ... */ } // Case-specific optimizations
Nell'esempio precedente, entrambi foo()
chiama lavoro , ma in un caso, otteniamo la migliore risoluzione del metodo in overload.
Esempio: ottimizzazione del compilatore
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; }
}
Nell'esempio precedente, entrambe le chiamate .Foo()
chiamano in definitiva lo stesso metodo override
che restituisce 2
. Solo, nel primo caso, esiste una ricerca metodo virtuale per trovare il metodo corretto; questa ricerca del metodo virtuale non è necessaria nel secondo caso poiché sealed
di quel metodo.
Credito a @Ben che ha fornito un esempio simile in sua risposta .
Vantaggio 2: ulteriori informazioni per il lettore
Conoscere il tipo esatto, ovvero Child
, fornisce più informazioni a chiunque stia leggendo il codice, rendendo più facile vedere cosa sta facendo il programma.
Certo, forse non importa il codice effettivo poiché sia parent.Foo();
che child.Foo();
hanno senso, ma per qualcuno che vede il codice per la prima volta, più informazioni sono semplicemente utili.
Inoltre, a seconda dell'ambiente di sviluppo, l'IDE può essere in grado di fornire suggerimenti e metadati più utili su Child
rispetto a Parent
.
Vantaggio 3: più pulito, codice più standardizzato
La maggior parte degli esempi di codice C # che ho visto ultimamente utilizzano var
, che in pratica è una scorciatoia per 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
La visualizzazione di una dichiarazione di dichiarazione non- var
non ha effetto; se c'è un motivo situazionale per questo, fantastico, ma per il resto sembra anti-pattern.
// 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();
Vantaggio 4: logica di programma più mutabile per la prototipazione
I primi tre vantaggi erano i grandi; questo è molto più situazionale.
Tuttavia, per le persone che usano il codice come gli altri usano Excel, cambiamo continuamente il nostro codice. Forse non abbiamo bisogno di chiamare un metodo unico per Child
nella questa versione del codice, ma potremmo riutilizzare o rielaborare il codice in seguito.
Il vantaggio di un sistema di tipo strong è che ci fornisce certi metadati sulla nostra logica di programma, rendendo le possibilità più facilmente evidenti. Questo è incredibilmente utile nella prototipazione, quindi è meglio tenerlo dove possibile.
Sommario
L'utilizzo di Parent
compromette la risoluzione del metodo sovraccarico, inibisce alcune ottimizzazioni del compilatore, rimuove le informazioni dal lettore e rende il codice più brutto.
Usare var
è davvero la strada da percorrere. È veloce, pulito, con motivi e aiuta il compilatore e l'IDE a fare il loro lavoro correttamente.
Importante : questa risposta riguarda circa Parent
rispetto a Child
nell'ambito locale di un metodo. Il problema di Parent
rispetto a Child
è molto diverso per i tipi restituiti, gli argomenti e i campi di classe.