2014-04-09 16 views
5

Questo è qualcosa che non ho mai notato prima, ma di recente ho incontrato. Quando ho incontrato questa situazione, sono rimasto sorpreso da ciò che il compilatore ha considerato corretto e da ciò che mi ha costretto a fare. Penso che sia più facile descritto attraverso l'esempio.Perché la mia sottoclasse è ancora generica quando fornisco un argomento di tipo alla classe base?

Diciamo che abbiamo una classe base generica con un solo metodo.

abstract class GenericBase<T> 
{ 
    public abstract T SomeMethod<T>(T value); 
} 

Niente pazzo qui. Ora, cerchiamo di estenderla, fornendo una concreta attuazione per int:

class IntImplementation : GenericBase<int> // T is now, and forever shall be, int 
{ 
    public override int SomeMethod(int value) 
    { 
     return ++value; 
    } 
} 

Sembra abbastanza semplice, giusto? Oppure, così ho pensato ... In effetti, non puoi fare . Il compilatore si lancia il messaggio

'IntImplementation' non implementa ereditato membro astratto 'GenericBase.SomeMethod (T)'

Ma ... T è ora un int! Perché non posso semplicemente sostituire questo nel mio override? Risulta l'unico accettabile override

public override T SomeMethod<T>(T value) 

che significa il metodo ora deve essere

public override T SomeMethod<T>(T value) 
{ 
    return ++((int)value); 
} 

Wow, che non è affatto generico. In effetti, potrei anche buttare i generici dalla classe base e andare con il buon vecchio object!

Mind. Soffiato. Sono stato sconcertante su quale potrebbe essere il ragionamento alla base di questo, ma sono in perdita. Qualcuno ha qualche idea?

+7

** Niente di pazzo qui **? Certamente no! Hai dichiarato due diversi parametri di tipo generico entrambi chiamati 'T'. Per favore, non farlo. Dovresti ricevere un avvertimento del compilatore che ti dice che questa è una cattiva pratica che porta a un codice confuso. –

+0

Mi sono imbattuto in una risposta e un commento. Non è giusto. :/Dat tipo argomento argomento generico .... – Will

risposta

23

Il T nel metodo generico non ha assolutamente nulla a che fare con lo T nella classe contenente e si dovrebbe ricevere un messaggio di avvertimento. Si prega di leggere gli avvertimenti del compilatore; sono lì per il tuo vantaggio.

Se si intende per SomeMethod per essere generico allora si dovrebbe essere scritta:

abstract class GenericBase<T> 
{ 
    public abstract U SomeMethod<U>(U value); 
} 

e ora è chiaro che GenericBase<int> non influisce SomeMethod<U> affatto.

O se è vostra intenzione che SomeMethod non può essere genericized a tutti allora non genericize esso:

abstract class GenericBase<T> 
{ 
    public abstract T SomeMethod(T value); 
} 

e ora si può ignorare SomeMethod come lei.

+0

Wow.Voglio dire, wow. Non avevo idea che fossero considerati tipi di parametri completamente diversi. Brb, ho intenzione di impersonare Vinnie Barbarino per la prossima ora. Whoah! Whoah. Whoooooah. – Will

Problemi correlati