2009-09-09 8 views
5

OK, ce titre est un peu floue, mais je ne peux pas penser à une meilleure façon de le mettre, autre que l'expliquer ...Est-il possible de détecter le contexte de classe dans une méthode statique héritée?

Dire que j'ai une classe Animal, avec une méthode statique, générique:

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

Et je Dog, les sous-classes Cat, Hamster etc. afin d'obtenir un Dog, je peux écrire:

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

o r

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

ce qui est vraiment la même chose. Mais il semble assez bête d'avoir à écrire Dog tant de fois, puisque j'appelle déjà la méthode statique à travers la sous-classe Dog.

Pouvez-vous penser à une façon intelligente d'écrire une méthode Create() dans la classe de base pour que je puisse invoquer

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

sans écrire une méthode Create() dans chacune des sous-classes?

Répondre

10

Vous pouvez rendre la classe Animal générique.

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> 
{ 

} 

Mais comment la classe Animal sait comment créer des instances de types dérivés?

+2

Vous voudrez probablement limiter 'T' à Animals:' class Animal où T: Animal ' – dtb

+0

@dtb: Bien sûr! Réponse mise à jour, merci. –

+0

Le code à l'intérieur de Create() appellera des méthodes virtuelles/abstraites, c'est ainsi qu'il créera des instances de types dérivés. –

2

Je ferais abstraction de la classe Animal avec une méthode Create statique; c'est effectivement un point de départ pour une usine. En fait, on dirait que vous êtes en train de défaire une classe d'usine.

Si vous ajoutez une méthode abstraite Initialiser à la classe des animaux, la méthode Create devient:

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

animal ne peut pas être une classe statique.Toutefois, si vous souhaitez déléguer la création à chaque type dérivé, il peut être judicieux de créer un résumé Animal et la méthode Initialize abstract au lieu de virtual. –

+0

Bonne prise. Ce n'était pas l'intention. –

+0

@Romain - bien, j'ai ajusté ma réponse. –

1

En plus des autres réponses sur les moyens autour, vous pouvez voir utiliser la réflexion que l'option Créer toujours toujours faire partie de Animal, pas la classe dérivée.

Questions connexes