Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to detect class context in an inherited static method?

OK, that title is a little unclear, but I can't think of a better way of putting it, other than explaining it...

Say I have a class Animal, with a static, generic method:

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

And I have subclasses Dog, Cat, Hamster etc. In order to get a Dog, I can write:

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

or

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

which is really the same thing. But it seems kinda silly to have to write Dog so many times, since I'm already invoking the static method through the Dog subclass.

Can you think of any clever way of writing a Create() method in the base class so that I could invoke

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

without writing a Create() method in each of the subclasses?

like image 527
Shaul Behr Avatar asked Sep 09 '09 15:09

Shaul Behr


2 Answers

You can make the Animal class generic.

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

}

But how the Animal class knows how to create instances of derived types?

like image 95
Romain Verdier Avatar answered Oct 28 '22 22:10

Romain Verdier


I would make the Animal class abstract with a static Create method; it's effectively a starting point for a factory. In fact, it looks like you're undoing a factory class.

If you add an abstract Initialize method to the Animal class, the Create method becomes:

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;
}
like image 36
Austin Salonen Avatar answered Oct 28 '22 23:10

Austin Salonen