2010-06-06 18 views
5

Ho due classi, una classe base e una classe figlio. Nella classe base definisco un metodo virtuale generico:Generici bizzarici errore di compilazione

protected virtual ReturnType Create<T>() where T : ReturnType {}

Poi nella mia classe figlio cerco di fare questo:

protected override ReturnTypeChild Create<T>() // ReturnTypeChild inherits ReturnType 
{ 
    return base.Create<T> as ReturnTypeChild; 
}

studio visivo dà questo strano errore:

The type 'T' cannot be used as type parameter 'T' in the generic type or method 'Create()'. There is no boxing conversion or type parameter conversion from 'T' to 'ReturnType'.

La ripetizione della clausola where sull'override del bambino restituisce anche un errore:

Constraints for override and explicit interface implementation methods are inherited from the base method, so they cannot be specified directly

Quindi cosa sto facendo di sbagliato qui?

+0

Se questo deve essere 'protetto override BarChild Foo ()'? Puoi dare nomi propri? Foo e Bar mi fanno male alla testa. – Kobi

+0

E non dovrebbe essere la base di ritorno.Fai come BarChild() ;? – GenericTypeTea

+1

Il tuo codice ha tutti i tipi di problemi (ad esempio, il metodo sottoposto a override manca del suo parametro generico, la tua dichiarazione di ritorno ha parentesi nel posto sbagliato, ecc.). È più probabile che tu ottenga risposte utili se crei una riproduzione minima del tuo problema che risolva tutti i problemi ovvi. – kvb

risposta

3

Questo funziona. Si doveva fare il tipo di ritorno generico:

public class BaseClass { 
    public virtual T Create<T>() where T : BaseClass, new() { 
    var newClass = new T(); 
    //initialize newClass by setting properties etc 
    return newClass; 
    } 
} 

public class DerivedClass : BaseClass { 
    public override T Create<T>() { 
    var newClass = base.Create<T>(); 
    //initialize newClass with DerivedClass specific stuff 
    return newClass; 
    } 
} 

void Test() { 

DerivedClass d = new DerivedClass() ; 
d.Create<DerivedClass>(); 
} 

Questi sono alcuni di base C# override rules:

The overridden base method must have the same signature as the override method.

Ciò significa lo stesso tipo di ritorno e stessi argomenti del metodo.

+0

puoi modificare ancora 1 volta? le classi devono essere indentate per formattare correttamente AFAICT –

+0

Oops, corretto. –

2

L'override non può modificare il tipo di ritorno, anche se il tipo di ritorno deriva dal tipo di ritorno del metodo della classe base. Devi fare qualcosa di simile a ciò che ha fatto Igor sopra, e rendere il tipo di ritorno generico.