Delphi类的C#

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

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

在Delphi中,我已经编写了数百个使用以下设计的类工厂(这里很简单):

unit uFactory; interface type TClassofMyClass = class of TMyClass; TFactoryDict = TDictionary; 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#中没有 ‘类’类型。 我错过了什么吗? 如何在C#中简单而优雅地实现这种类型的工厂? 这个设计也可以在Python中实现 – 为什么C#会更糟??

你可以使用Type:

 Dictionary TypeDictionary = new Dictionary(); 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(): where T is MyBaseClass { var type = typeof(T); var constructor = type.GetConstructor(....); return constructor.Invoke(....) as T; } 

以下是参数化构造的多种选择:

 public T Factory(params object[] args): where T is MyBaseClass { var argList = new List(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 …

  class Potato { } class Potato1 : Potato { public Potato1(object[] param) { } } class Potato2 : Potato { public Potato2(object[] param); } enum MyEnum { E1, E2 } Dictionary> dict = new Dictionary>(){ {MyEnum.E1,(d)=>new Potato1(d)}, {MyEnum.E2,(d)=>new Potato2(d)} }; Potato Factory(MyEnum e, object[] param) { return dict[e](param); } 

如果我理解你是正确的,你想要一个静态类的引用。 这在c#中是不可能的。

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

C#语言不支持元类。

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

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

另一个常用的选项是使用reflection来完成它,这将允许您编写更接近您习惯的代码。

另一种选择是使用返回对象的新实例的委托字典替换您的类字典。 使用lambda语法,该选项可以产生非常干净的代码。

reflection的缺点是你放弃了编译时类型的安全性。 因此,虽然基于reflection的方法可能最接近问题中的delphi代码,但这不是我个人会选择的路线。

我建议你寻找最惯用的C#解决方案,而不是试图将你的Delphi解决方案变成一种不需要这种方法的语言。 从类工厂的Web搜索开始。