在C#的Delphi类(Delphi Class of in C#)

2019-08-20 05:40发布

我知道这个问题已经被问过,但我还没有看到很短的,明确的答案,所以我希望他们不会删除这个问题,我现在会得到一个明确的答案:

我目前的工作在C#5.0; .NET 4.5; 2012年VS我主要是一个Delphi的人,虽然我已经做了很多用C#。

在Delphi我已经写了数百个使用下面这种设计(大大简化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.

现在:我该怎么做在C#这样的事情? 似乎有在C#NO“类的”类型。 我缺少的东西吗? 我如何在C#中简单而优雅实现这种类型的类工厂的? 这样的设计可以在Python中实现,以及 - 为什么C#是雪上加霜?

Answer 1:

您可以使用类型:

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如果不能找到匹配的构造函数...



Answer 2:

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


Answer 3:

如果我理解你纠正你想拥有一个静态类的引用。 这是不可能在C#。

工厂方法实现的一个例子: http://www.codeproject.com/Tips/328826/implementing-Factory-Method-in-Csharp



Answer 4:

C#语言不支持元类。

所以你必须实行以另一种方式您的工厂。 一种方法是使用switch语句上的枚举:

switch (aEnum)
{
     case myEnum1:
         return new MyClass1();
     case myEnum2:
         return new MyClass2();
     .....
}

另一种常用的方法是与反思,这将允许你写的代码更接近你是用来做什么,做到这一点。

而另一种选择是,以取代你的类字典,返回你的对象的新实例代表的字典。 随着拉姆达语法选项产生非常干净的代码。

反射的缺点是你放弃编译时类型安全。 因此,虽然反射为基础的方法可能是最接近问题的Delphi代码,这不是我个人会选择的路线。

而不是试图鞋拔你的Delphi的解决方案为,不希望这种做法一门语言,我建议你寻找最地道的C#解决方案。 先从网上搜索类工厂。



文章来源: Delphi Class of in C#