【问题标题】:Can I create an instance of a derived class based on a certain property defined in my abstract base class?我可以根据抽象基类中定义的某个属性创建派生类的实例吗?
【发布时间】:2019-03-12 15:59:16
【问题描述】:

基本上我有一个抽象类,我们会说两个属性,一个是抽象类,一个是派生类。

public abstract class BaseClass { 
    public string ID { get; set; } 
    public abstract string Name { get; };
}

public class Class1 : BaseClass { // id would be 1
    public string Name { get { return "Class1 Name"; }
}

public class Class2 : BaseClass {
    public string Name { get { return "Class2 Name"; }
}

public class Class3 : BaseClass {
    public string Name { get { return "Class3 Name"; }
}

然后我的数据层中有一个方法,它基本上返回基类的 ID 列表。我要问的是,如果没有 if 或 switch 语句,我是否可以根据这些 ID 创建 DerivedClass 的新实例?所以……

List<BaseClass> list = new List<BaseClass>();
string id = dataReader["ID"].ToString(); // say this id = 1
list.Add(new BaseClass { ID = id }); // this would be "Class1 Name" and the Class would be Class1

我知道我无法创建抽象类的新实例,因此“new BaseClass()”不起作用,但这是我知道如何解释它的唯一方法。我已经研究过使用反射制作副本或克隆,但不确定它是否真的会做我想要的。这可能不太可能,但我想我会问的。

【问题讨论】:

  • 使用factory method pattern 的变体。创建一个静态方法(在 BaseClass 中或在用作工厂的单独类中),其目的是根据传递给静态方法的某些参数创建并返回具体类型的实例...
  • 谢谢,这就是我要找的东西,而不是在我创建类的任何地方都有逻辑,只需将它放在一个地方。然而,实现是让我绊倒的地方,如果将来要添加新的派生类,我不想更新工厂。

标签: c# reflection .net-core asp.net-core-mvc open-closed-principle


【解决方案1】:

怎么样:

switch(id) {
   case "1": list.Add(new Class1());
   break;
   ...
}

你也可以使用:

list.Add((BaseClass)Activator.CreateInstance("AssemblyName", "Class"+id));

另见How do I instantiate a class given its string name?

【讨论】:

  • 开关是更好的方法。如果没有必要,你应该避免使用反射。
【解决方案2】:

创建一个字典,其中包含与其 id 关联的类型(其值将在您将依赖的字符串属性中):

Dictionary<string, Type> dictOfTypes = new Dictionary<string, Type>();
dictOfTypes.Add("1", typeof(Class1));

然后根据您拥有的 id,您可以从 Dictionary 获取项目,然后创建实例:

string id = "1";
Type classType = dictOfTypes[id];
var instance = Activator.CreateInstance(classType);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-09-10
    • 2015-03-23
    • 1970-01-01
    • 1970-01-01
    • 2011-11-05
    • 2014-09-29
    • 1970-01-01
    相关资源
    最近更新 更多