3

我有一定数量的类继承自抽象类:

abstract public class baseClass
{
    //logics
}

public class child1 : baseClass
{
}

public class child2 : baseClass
{
}

现在我有一些管理类,它们必须根据一个枚举创建这些类之一,该枚举的值将具有相同的名称,如下所示:

public enum ClassType
{
    child1,
    child2
}

public class Manager
{
    private List<baseClass> _workers;

    public void Initialize(ClassType type)
    {
        //what logics to put here? (resulting in correctChild)
        _workers.Add(correctChild);
    }
}

我在考虑 typeof 但不知道如何实现它。注意:在这个例子中它是 2 个类,但在实际情况下它是任意数量的类。

4

4 回答 4

6

看看Activator.CreateInstance()

使用命名程序集和默认构造函数创建指定名称的类型的实例。

所以代码看起来像

Activator.CreateInstance(type.ToString(),assemblyName);

我实际上熟悉这样的实现,我自己也使用过。我还建议查看这篇文章,该文章解释了如何实际使用枚举值的属性来存储实际的类名。您甚至可以将其用作扩展程序。

 public static string Description(this Enum enumValue) {
        Type enumType = enumValue.GetType();
        FieldInfo field = enumType.GetField(enumValue.ToString());
        object[] attributes = field.GetCustomAttributes(typeof(DescriptionAttribute), false);
        return attributes.Length == 0 ? enumValue.ToString() : ((DescriptionAttribute)attributes[0]).Description;
}

然后代码看起来像

Activator.CreateInstance(classType.Description(), assemblyName);
于 2013-03-16T16:42:20.873 回答
1

如果您不需要属性的开销并且您从同一个程序集中运行它 - 您可以只使用正在执行的程序集通过反射加载类型。Activator.CreateInstance可以动态地为您构建对象。

public class Manager
{
    private List<baseClass> _workers = new List<baseClass>();

    public void Initialize(ClassType type)
    {
        string assemblyName = Assembly.GetExecutingAssembly().GetName().Name;
        Type objType = Type.GetType(string.Format("{0}.{1},{0}", assemblyName, type.ToString()));
        var correctChild =  (baseClass)Activator.CreateInstance(objType);
        _workers.Add(correctChild);
    }
}
于 2013-03-16T16:53:32.870 回答
0

有很多方法可以区分类型。

您可以使用is运算符

var o = ...;
if (o is Child1) {}

或者你可以使用as运算符

var child = o as Child1;
if (child != null) {}

或者您已经描述过自己的内容,typeof操作员。

不过,我感觉到的是,如果您对类型转换有强烈的需求,那么手头可能还有其他东西。也许您可以通过Polymorphism解决您的问题。然后您不必区分冗长if-elsecase-switch构造中的所有不同类型,但您可以将“不同行为”委托给您的子类。

于 2013-03-16T16:36:47.367 回答
0

如果你不想使用 if 语句,你可以使用 case 语句吗?喜欢:

public class Manager
{
    private List<baseClass> _workers;

    public void Initialize(ClassType type)
    {
        switch (type)
        {
            case child1:
              _workers.Add(correctChild);
              break;
            case child2:
              _workers.Add(correctChild);
              break;
        }
    }
}
于 2013-03-16T16:39:56.667 回答