10

この質問が以前に聞かれたことは知っていますが、簡潔で明確な回答をまだ見ていないので、この質問が削除されないことを願っています。明確な回答が得られるでしょう。

私は現在 C# 5.0 で作業しています。.NET 4.5; VS 2012. C# で多くのことを行ってきましたが、私は主に Delphi の男です。

Delphi では、次の種類の設計を使用する何百ものクラス ファクトリを作成しました (ここでは非常に単純化されています)。

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.

今: C# でこのようなことを行うにはどうすればよいですか?! C#には' class of ' 型がないようです。何か不足していますか?このタイプのクラス ファクトリを C# で簡単かつエレガントに実装するにはどうすればよいですか? この設計は Python でも実装できます。なぜ C# の方が悪いのでしょうか?!

4

4 に答える 4

9

タイプを使用できます:

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(....);
}

しかし、一般的な方法を使用する必要があると思います:

public T Factory<T>(): where T is MyBaseClass
{
    var type = typeof(T);
    var constructor = type.GetConstructor(....);
    return constructor.Invoke(....) as T;
}

パラメータ化された構築のバリエーションは次のとおりです。

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;
}

そしてもちろん; 最初の例と同様に、一致するコンストラクターが見つからない場合、これは nullpointerexception をスローします...

于 2013-04-08T07:20:16.520 に答える
4
    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);
    }
于 2013-04-08T07:27:11.967 に答える