2009-09-09 12 views
5

bien, ese título es un poco confuso, pero no puedo pensar en una mejor manera de decirlo, aparte de explicarla ...¿Es posible detectar el contexto de clase en un método estático heredado?

Decir que tengo una clase Animal, con un método estático, genérica:

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

Y tengo subclases Dog, Cat, Hamster etc. con el fin de obtener una Dog, puedo escribir:

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

o r

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

que es realmente lo mismo. Pero parece un poco tonto tener que escribir Dog tantas veces, ya que estoy invocando el método estático a través de la subclase Dog.

¿Se puede pensar en ninguna forma inteligente de escribir un método Create() en la clase base para que pudiera invocar

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

sin escribir un método Create() en cada una de las subclases?

Respuesta

10

Puede hacer que la clase Animal sea genérica.

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

} 

Pero cómo la clase Animal sabe cómo crear instancias de tipos de derivados?

+2

Probablemente desee restringir 'T' a Animals:' class Animal donde T: Animal ' – dtb

+0

@dtb: Sure! Respuesta actualizada, gracias. –

+0

El código dentro de Create() llamará a los métodos virtuales/abstractos, así creará instancias de tipos derivados. –

2

Haría el resumen de la clase Animal con un método Create estático; es efectivamente un punto de partida para una fábrica. De hecho, parece que estás deshaciendo una clase de fábrica.

Si añade un resumen método Inicializar para la clase de animal, el método Create se convierte en:

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 no puede ser una clase estáticaSin embargo, si desea delegar la creación a cada tipo derivado, podría ser una buena idea hacer Abstract Animal y el método Initialize abstract en lugar de virtual. –

+0

Buena captura. Esa no era la intención. –

+0

@Romain - bien puesto, ajusté mi respuesta. –

1

Además de las otras respuestas en formas a su alrededor, se puede ver utilizando la reflexión que crean siempre seguir siendo parte de Animal, no de la clase derivada.

Cuestiones relacionadas