【问题标题】:How to define a "List" of derived classes?如何定义派生类的“列表”?
【发布时间】:2013-04-19 19:27:53
【问题描述】:

我有一个基类和一些派生类

public class MyBase {...}
public class MyClass1 : MyBase {...}
public class MyClass2 : MyBase {...}

现在我想列出这些派生类(类!!不是类的实例!),然后我想随机创建这些派生类之一的一个实例。

这是如何工作的??

这是我想要的伪 C# :)

List<MyBase> classList = new List<MyBase> () { MyClass1, MyClass2, MyClass3, ...}

MyBase randomInstance = new classList[random.Next(0,classList.Count-1)]();

(不幸的是,这个 List 构造需要 MyBase 的实例,而不是类名)

【问题讨论】:

    标签: c# class types derived


    【解决方案1】:

    类似的东西(假设一个无参数的构造函数,并且 B 和 C 是从 A 派生的):

    List<Type> types = new List<Type> { typeof(A), typeof(B), typeof(C) };
    
    A instance = (A)Activator.CreateInstance(types[r.Next(0, types.Count)]);
    

    【讨论】:

    • 不要忘记要使用这种方法,列表中的每个类型都必须具有具有相同语义的构造函数。默认的无参数构造函数可以,但只要每种类型都有一个具有相同签名的构造函数,你就可以开始了。
    • 警告:这种方法唯一真正的好处是简洁。编译器不会阻止您自爆,因为它都是运行时类型信息。
    • 当你想处理一个不确定的类型(泛型之外)时,你无论如何都会失去类型安全性。
    【解决方案2】:

    您可以从这样的类型创建

    class MyBase
    {
    }
    
    class MyClass1 : MyBase
    {
    }
    
    class MyClass2 : MyBase
    {
    }
    

    这使用System.Activator 来创建对象。

    void Main()
    {
        var typesToPickFrom = new List<Type>()
        {
            typeof(MyBase),
            typeof(MyClass1),
            typeof(MyClass2)
        };
    
        var rnd = new Random();
        Type typeToCreate = typesToPickFrom [rnd.Next(typesToPickFrom.Count)];
        object newObject = Activator.CreateInstance(typeToCreate);
    }
    

    您可以根据需要进行投射。

    【讨论】:

    • 我要说你的索引器中有一个 off-by-1 溢出问题,但我忘记了上限是独占的。修正了我自己的答案。 :)
    【解决方案3】:

    如您所说,如果您想“创建”一个随机实例:

    var selection = random.Next(0,2)
    
    switch (selection)
    {
        case 1: return new MyBase();
        case 2: return new MyClass1();
        case 3: return new MyClass2();
    }
    

    为所有这些类定义一个公共的interface 可能很有用,这样您就可以从方法中返回一些东西。或者,您可以简单地返回 objectdynamic

    【讨论】:

    • 返回类型可能是MyBase,因为所有的类都是或继承自MyBase
    猜你喜欢
    • 2013-12-27
    • 1970-01-01
    • 2018-05-09
    • 1970-01-01
    • 2010-10-29
    • 1970-01-01
    • 2012-05-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多