2

这是对上一个问题的跟进。这个问题有一个错误(我实际上发布了我当前的解决方案,而不是我正在寻找的更好的解决方案)。

我有 3 节课,ParentClass, ClassA, ClassB. ClassA和都是ClassB的子类ParentClass。我想尝试创建类型的对象ClassAClassB使用某种枚举来识别类型,然后将对象实例化为父类型。我怎样才能动态地做到这一点?请看下面的代码,以及上面写着的部分//what do I put here?。谢谢阅读!

公共枚举 ClassType { ClassA, ClassB };

public abstract class ParentClass
{
    public static readonly Dictionary<ClassType, Type> Types = 
        new Dictionary<ClassType, Type>{
            {ClassType.ClassA, typeof(ClassA) },
            {ClassType.ClassB, typeof(ClassB) }
        };

    public ParentClass()
    {
        //....
    }

    public static ParentClass GetNewObjectOfType(ClassType type)
    {
        //What do I put here?
    }
}

public class ClassA:ParentClass
{
    //....
}
public class ClassB:ParentClass
{
    //.......
}
4

3 回答 3

2

您可以使用Activator该类轻松完成此操作,尤其是在构造函数没有任何参数的情况下:

return Activator.CreateInstance(Types[type]);

于 2013-02-20T23:15:47.537 回答
2

重申您的问题:您正在寻找有关如何编写静态工厂方法的建议。

我认为您不需要单独的枚举来完成此操作。这是我放在一起的 LINQPad 脚本(编辑:添加静态常量,使用它们创建演示)

void Main()
{
    var a = ParentClass.Create(typeof(ClassA));
    var b = ParentClass.Create(typeof(ClassB));
    var c = ParentClass.Create(ParentClass.ClassAType);
    a.Dump();
    b.Dump();
    c.Dump();
}


public abstract class ParentClass
{
    public static readonly Type ClassAType = typeof(ClassA); 
    public static readonly Type ClassBType = typeof(ClassB);
    public string SomeProp { get; set; }
    protected ParentClass() {}

    public static ParentClass Create(Type typeToCreate)
    {
        // validate that type is derived from ParentClass
        return (ParentClass)Activator.CreateInstance(typeToCreate);
    }
}

public class ClassA:ParentClass {
    public ClassA()
    {
        SomeProp = "ClassA~";
    }

}
public class ClassB:ParentClass
{
    public ClassB()
    {
        SomeProp = "ClassB~";
    }
}
于 2013-02-20T23:22:28.680 回答
1

如上一个问题所述:

反射很慢,经常在不需要的地方使用

Activator.CreateInstance 使用反射来追踪无参数的构造函数。要解决这个问题 - 这不是必需的。父类已经知道它负责创建的所有类型。


使用静态工厂方法的原因之一是创建子类可能需要大量工作或不同类型的工作。我认为如果你加强你的地图,你会更容易编写静态工厂:

public static readonly Dictionary<ClassType, Func<ParentClass>> Types = 
    new Dictionary<ClassType, Func<ParentClass>>{
        {ClassType.ClassA, () => new ClassA(1, 2, 3) },
        {ClassType.ClassB, () => new ClassB("1") }
    };


public static ParentClass GetNewObjectOfType(ClassType type)
{
    Func<ParentClass> maker = Types[type];
    ParentClass result = maker();
    return result;
}
于 2013-02-20T23:31:01.097 回答