If you make is a single regular static method, it will abuse OOP, because it will require a
case
or
if
statement checking for some parameter of this method and calling different constructors.
If is possible to do automatically in some other languages supporting true
meta-classes and
virtual static classes; a very powerful way of making the class factory (example: Delphi Pascal). In .NET it is not possible.
You can do it through generic method though:
abstract class Person {
internal DERIVED Factory<DERIVED>()
where DERIVED : Person, new() {
return new DERIVED();
}
}
class Employee : Person {
internal protected Employee() { }
}
class Student : Person {
internal protected Student() { }
}
Student myStudent = Person.Factory<Student>();
Empoyee myEmpoyee = Person.Factory<Empoyee>();
On problem of this approach is: factory assumes the constructor used in the factory is private. In this case it won't work as it is needed for the factory implemented in the base class. So, the constructors can be only
internal protected.
Another possibility is using Reflection. You can pass the parameter of
System.Type
and instantiate it using
System.Reflection.ConstructorInfo
. It will take some effort and cannot be very useful. Why? Because there is not a meta-class, there is only one type called
System.Type
for all you classes. Therefore, you can not apply constraints like
DERIVED : Person, new()
. You won't be able to constrant the set of types to a classes derived from
Person
. This fact defeats the purpose of Reflection-based method.
After comparing these possibilities I would recommend to give up on a single method. Having a separate factory method in each derived class is much more practical and maintainable:
abstract class Person { }
class Employee : Person {
internal static Employee MakeInstance() { return new Employee(); }
private Employee() { }
}
Second practical method would be using generics as show above.
—SA