tl; dr - L' uso diChild
overParent
è preferibile nell'ambito locale. Non solo aiuta con la leggibilità, ma è anche necessario garantire che la risoluzione del metodo sovraccarico funzioni correttamente e aiuti a consentire una compilazione efficiente.
Nell'ambito locale,
Parent obj = new Child(); // Works
Child obj = new Child(); // Better
var obj = new Child(); // Best
Concettualmente, si tratta di mantenere il maggior numero possibile di informazioni. Se eseguiamo il downgrade a Parent
, stiamo essenzialmente eliminando le informazioni sul tipo che avrebbero potuto essere utili.
La conservazione delle informazioni complete sul tipo presenta quattro vantaggi principali:
- Fornisce ulteriori informazioni al compilatore.
- Fornisce ulteriori informazioni al lettore.
- Codice più pulito e più standardizzato.
- Rende la logica del programma più mutevole.
Vantaggio 1: maggiori informazioni al compilatore
Il tipo apparente viene utilizzato nella risoluzione del metodo sovraccaricata e nell'ottimizzazione.
Esempio: risoluzione del metodo sovraccaricata
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 sopra, entrambe le foo()
chiamate funzionano , ma in un caso otteniamo la migliore risoluzione del metodo sovraccarico.
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 sopra, entrambe le .Foo()
chiamate alla fine chiamano lo stesso override
metodo che restituisce 2
. Solo, nel primo caso, esiste una ricerca del metodo virtuale per trovare il metodo corretto; la ricerca di questo metodo virtuale non è necessaria nel secondo caso da quel metodo sealed
.
Ringraziamo @Ben che ha fornito un esempio simile nella sua risposta .
Vantaggio 2: maggiori informazioni per il lettore
Conoscere il tipo esatto, ovvero Child
, fornisce maggiori informazioni a chiunque stia leggendo il codice, rendendo più semplice vedere cosa sta facendo il programma.
Certo, forse non importa il codice reale poiché entrambi parent.Foo();
e child.Foo();
hanno senso, ma per qualcuno che vede il codice per la prima volta, ulteriori informazioni sono semplicemente utili.
Inoltre, a seconda dell'ambiente di sviluppo, l'IDE potrebbe essere in grado di fornire tooltip e metadati più utili Child
rispetto a Parent
.
Vantaggio 3: codice più pulito e più standardizzato
La maggior parte degli esempi di codice C # che ho visto di recente usano var
, che è sostanzialmente 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
Vedere una var
dichiarazione di non dichiarazione sembra appena fuori; se c'è un motivo situazionale per questo, fantastico, ma per il resto sembra anti-schema.
// 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 del programma più mutevole per la prototipazione
I primi tre vantaggi erano quelli grandi; questo è molto più situazionale.
Tuttavia, per le persone che usano il codice come gli altri usano Excel, cambiamo costantemente il nostro codice. Forse non è necessario chiamare un metodo univoco Child
in questa versione del codice, ma potremmo riutilizzare o rielaborare il codice in un secondo momento.
Il vantaggio di un sistema di tipo forte è che ci fornisce alcuni metadati sulla logica del nostro programma, rendendo le possibilità più evidenti. Questo è incredibilmente utile nella prototipazione, quindi è meglio tenerlo dove possibile.
Sommario
L'utilizzo di Parent
una risoluzione del metodo sovraccarica compromette, inibisce alcune ottimizzazioni del compilatore, rimuove le informazioni dal lettore e rende il codice più brutto.
L'utilizzo var
è davvero la strada da percorrere. È rapido, pulito, strutturato e aiuta il compilatore e l'IDE a svolgere correttamente il proprio lavoro.
Importante : questa risposta riguardaParent
vs.Child
nell'ambito locale di un metodo. Il problema diParent
vs.Child
è molto diverso per tipi di ritorno, argomenti e campi di classe.