抽象类实例化

时间:2011-12-20 18:46:02

标签: c# generics constructor

我有一个基本的抽象类,有几个扩展和覆盖它的类,但是它们都有相同的构造函数。现在我从switch语句中调用每个构造函数:

case 1: return new A(arg1); // arg is int

等,大约10个班级。是否有一种方法可以使用泛型或委托来创建一个方法来获取类名并使用参数实例化该类型?

这会有所帮助,因为如果我对构造函数进行更改,我还必须更改每个实例化。

代表是最直接的,但研究表明不会为代表分配构造函数。

此外: 我现在使用笔记本电脑上网而不仅仅是我的手机,所以这里有一些代码。

这是现在发生的事情的一个例子:

switch (new Random().Next(4))
{
    case 3:
         // classA : baseClass, args{int, bool, otherClass}
         return new classA(arg1, arg2, arg3);
    case 2:
         // classB : baseClass, args{int, bool, otherClass}
         return new classB(arg1, arg2, arg3);
    case 1:
         // classC : baseClass, args{int, bool, otherClass}
         return new classC(arg1, arg2, arg3);
    case 0:
         // classD : baseClass, args{int, bool, otherClass}
         return new classD(arg1, arg2, arg3);
    default:
         continue;
}

我想在块的末尾用三个参数调用一个实例化器。

我想到的一个解决方案是使make和instantiator类与此类似:

ClassInstantiator inst = new ClassInstantiator(arg1, arg2, arg3);
switch(new Random().Next(4))
{
     case 4:
         return inst.instantiate<classA>();
     ...
}

这是否已内置于该语言中,或者是否有人知道更优雅的解决方案?

4 个答案:

答案 0 :(得分:5)

你无法摆脱这样一个事实:某些东西必须在条件基础上决定构建什么,但你可以封装它。我可以向您展示一种最受欢迎​​的GOF模式:http://en.wikipedia.org/wiki/Factory_method_pattern

e.g。

public abstract class MyBase(string name){}
public class Concrete1 : MyBase{}
public class Concrete2 : MyBase{}

public class MyFactory
{
   public MyBase Create(Criteria criteria)
   {
       //conditional logic/reflection
   }
}

答案 1 :(得分:5)

可以放在泛型类型上的唯一与构造函数相关的约束是new()约束,它需要一个公共无参数构造函数。

你可以用反射;该示例假定所有相关类型都有一个带有int的构造函数,如示例所示,并且抽象基类被称为B

public T CreateInstance<T>(int i) where T : B
{
    return (T)Activator.CreateInstance(typeof(T), i);
}

然后你会这样称呼它:

A a = CreateInstance<A>(3);

答案 2 :(得分:1)

您可以创建一个字典,其中类名作为键,构造函数委托作为值。

Dictionary<string,Func<int,BaseClass>> _dict = new Dictionary<string,Func<int,BaseClass>>();
_dict.Add("ClassA", i => new ClassA(i));
_dict.Add("ClassB", i => new ClassB(i));

// Create ClassA object by class name
BaseClass obj = _dict["ClassA"](5);

答案 3 :(得分:0)

我的意思并不是要使你的问题过于复杂,但如果你发现你有很多这类代码,那么你可能会对使用IoC容器感兴趣。

热门的IoC容器: