2010-04-20 18 views
22

Ho questo codice nella classe di baseimperativi ereditato metodi generici

protected virtual bool HasAnyStuff<TObject>(TObject obj) where TObject:class 
    { 
     return false; 
    } 

In classe figlia sto imperativi

protected override bool HasAnyStuff<Customer>(Customer obj) 
    { 
    //some stuff 
     if Customer.sth etc 
     return false; 
    } 

sto ottenendo questo errore

parametro Type '' ' la dichiarazione deve essere un identificatore non un tipo '' '

Cosa sto facendo di sbagliato qui?

risposta

39

Non è possibile sovrascrivere un parametro di tipo di un metodo generico in una classe derivata. Per ottenere una funzionalità simile, una possibilità è quella di avere la classe di base sia una classe generica, e avere la vostra classe derivata come

class Derived : BaseClass<Customer> 
{ 
    protected override bool HasAnyStuff(Customer customer) 
    { 
     // ... 
    } 
} 

dove BaseClass è dichiarato come

class BaseClass<T> where T : class 
{ 
    // ... 
    protected virtual bool HasAnyStuff(T obj) 
    { 
     // ... 
    } 
} 

In alternativa, a seconda esattamente Come viene utilizzata la classe derivata, è possibile ignorare il metodo HasAnyStuff con un argomento non generico Customer.

public bool HasAnyStuff(Customer customer) 
{ 
    // ... 
} 

Tuttavia, si noti che la nuova HasAnyStuff non sarà chiamato, se non si lavora con un'istanza di DerivedClass. Vale a dire,

BaseClass foo = new DerivedClass(); 
foo.HasAnyStuff(new Customer()); 

chiamerà 's metodo generico, non DerivedClass' BaseClass s metodo non generico.

0

Ho avuto lo stesso caso d'uso che stai cercando. C'è un metodo generico sulla classe base e voglio sovrascrivere il metodo per un solo tipo. Per tutti gli altri tipi, volevo che il metodo si comportasse nello stesso modo. Ecco un semplice esempio basato sulla tua domanda.

class BaseClass 
{ 
    protected virtual bool HasAnyStuff<TObject>(TObject obj) 
    { 
     return false; 
    } 
} 

class DerivedClass : BaseClass 
{ 
    protected override bool HasAnyStuff<TObject>(TObject obj) 
    { 
     if (typeof(TObject) != typeof(AlarmTran)) return base.HasAnyStuff<TObject>(obj); 

     //some stuff 
     //if Customer.sth etc 
     return false; 
    } 
} 

Si può anche invertire la logica if di gestire più sostituzioni per molti tipi diversi.

protected override bool HasAnyStuff<TObject>(TObject obj) 
{ 
    if (typeof(TObject) == typeof(AlarmTran)) 
    { 
     //some stuff 
     //if Customer.sth etc 
     return false; 
    } 
    else if (typeof(TObject) == typeof(...)) 
    { 
     ... 
     return ...; 
    } 

    return base.HasAnyStuff<TObject>(obj); 
} 
0

Simile alla risposta di John Carpenter, è possibile eseguire l'override del metodo generico con lo stesso metodo generico, ma è sufficiente utilizzare l'operatore as di controllare e cast al tipo desiderato. Questo ha il vantaggio aggiuntivo di utilizzare il test nulla per verificare se la conversione ha funzionato.

Base Class

protected virtual bool HasAnyStuff<TObject>(TObject obj) 
{ 
    .... // base implementation 
} 

Ereditato Classe

protected override bool HasAnyStuff<TObject>(TObject obj) 
{ 
    var customer = obj as Customer; 
    if (customer == null) // conversion failed. object is not of type Customer 
    { 
     return base.HasAnyStuff(obj); 
    } 

    .... // do stuff with the customer 
}