I know this question has been asked before, but I have yet to see a short, clear answer, so I'm hoping they won't remove this question and I will now get a clear answer:
I am currently working in C# 5.0; .NET 4.5; VS 2012. I am mostly a Delphi guy although I've done lots with C#.
In Delphi I have written hundreds of class factories that use the following sort of design (MUCH SIMPLIFIED HERE):
unit uFactory;
interface
type
    TClassofMyClass = class of TMyClass;
    TFactoryDict = TDictionary<TMyEnum, TClassofMyClass>;
var fDict:TFactoryDict;
implementation  
procedure initDict;
begin
    fDict:=TFactoryDict.create;
    fDict.add(myEnum1, TMyClass1);
    fDict.add(myEnum2, TMyClass2);
    fDict.add(myEnum3, TMyClass3);
end;
function Factory(const aEnum: TMyEnum): TMyClass;
var
    ClassofMyClass: TClassofMyClass;
begin
    if fDict.TryGetValue(aEnum, ClassofMyClass) then
    result := ClassofMyClass.Create(aParam);
end;
end.
Now: HOW do I do something like this in C#?! Seems there is NO 'class of ' type in C#. Am I missing something? How can I implement this type of class factory simply and elegantly in C#? This design can be implemented in Python as well - why should C# be worse?!
    class Potato
    {
    }
    class Potato1 : Potato
    {
        public Potato1(object[] param) { }
    }
    class Potato2 : Potato
    {
        public Potato2(object[] param);
    }
    enum MyEnum
    {
        E1, E2
    }
    Dictionary<MyEnum, Func<object[], Potato>> dict = new Dictionary<MyEnum, Func<object[], Potato>>(){
            {MyEnum.E1,(d)=>new Potato1(d)},
            {MyEnum.E2,(d)=>new Potato2(d)}
        };
    Potato Factory(MyEnum e, object[] param)
    {
        return dict[e](param);
    }
                        You can use Type:
Dictionary<ClassEnum, Type> TypeDictionary = new Dictionary<ClassEnum, Type>();
public void InitDictionary()
{
    TypeDictionary.Add(ClassEnum.FirstClass, typeof(FirstClass));
    //etc...
}
public object Factory(ClassEnum type)
{
    if (!TypeDictionary.ContainsKey(type))
        return null;
    var constructor = TypeDictionary[type].GetConstructor(....);
    return constructor.Invoke(....);
}
But I think you should use a generic method:
public T Factory<T>(): where T is MyBaseClass
{
    var type = typeof(T);
    var constructor = type.GetConstructor(....);
    return constructor.Invoke(....) as T;
}
Here is a variety for parameterized construction:
public T Factory<T>(params object[] args): where T is MyBaseClass
{
    var argList = new List<object>(args);
    var type = typeof(T);
    var argtypes = argList.Select(o => o.GetType()).ToArray();
    var constructor = type.GetConstructor(argtypes);
    return constructor.Invoke(args) as T;
}
And of course; As with the first example, this will throw a nullpointerexception if it can't find a matching constructor...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With