2009-09-09 14 views
5

OK, quel titolo è un po 'poco chiaro, ma non riesco a pensare ad un modo migliore per dirlo, diverso da quello spiegarlo ...È possibile rilevare il contesto di classe in un metodo statico ereditato?

Dire Ho una classe Animal, con un metodo generico static:

public static T Create<T>() where T : Animal { 
    // stuff to create, initialize and return an animal of type T 
} 

E ho sottoclassi Dog, Cat, Hamster ecc al fine di ottenere un Dog, posso scrivere:

Dog d = Animal.Create<Dog>(); 

o r

Dog d = Dog.Create<Dog>(); 

che è davvero la stessa cosa. Ma sembra un po 'sciocco dover scrivere Dog così tante volte, dal momento che sto già invocando il metodo statico attraverso la sottoclasse Dog.

Riuscite a pensare a un modo intelligente di scrivere un metodo Create() nella classe base in modo che potessi richiamare

Dog d = Dog.Create(); 
Cat c = Cat.Create(); 
Hamster h = Hamster.Create(); 

senza scrivere un metodo Create() in ciascuna delle sottoclassi?

risposta

10

È possibile rendere generica la classe Animale.

class Animal<T> where T : Animal<T> 
{ 
    public static T Create() 
    { 
     // Don't know what you'll be able to do here 
    } 
} 

class Dog : Animal<Dog> 
{ 

} 

Ma come la classe Animal sa come creare istanze di tipi derivati?

+2

Probabilmente vorrete limitare 'T' a Animali:' classe Animal dove T: Animal ' – dtb

+0

@dtb: Certo! Risposta aggiornata, grazie. –

+0

Il codice all'interno di Create() chiamerà metodi virtuali/astratti, è così che creerà istanze di tipi derivati. –

2

Farei l'abstract della classe Animal con un metodo Create statico; è effettivamente un punto di partenza per una fabbrica. In effetti, sembra che tu stia annullando una classe di fabbrica.

Se si aggiunge un abstract metodo Initialize alla classe degli animali, il metodo Create diventa:

public static T Create<T>() where T : Animal { 
    T animal = new T(); //may need a "new" in the declaration 
    animal.Initialize(); //or Create or whatever or you put this logic 
         // in the constructor and don't call this at all. 
    return animal; 
} 
+0

animale non può essere una classe statica.Tuttavia, se si desidera delegare la creazione a ciascun tipo derivato, potrebbe essere una buona idea rendere Animal abstract e il metodo Initialize abstract anziché virtual. –

+0

Buona presa. Non era questo l'intento. –

+0

@Romain - beh, ho modificato la mia risposta. –

1

In aggiunta alle altre risposte su modi intorno ad esso, è possibile visualizzare utilizzando la riflessione che creano sempre essere ancora parte di Animal, non della classe derivata.

Problemi correlati