如何存储子类类型并能够用列表的位置实例化一个变量?

How to store subclass types and be able to instantiate a variable with the position of the list?

我正在 Unity 上用 C# 开发一款游戏,旨在学习 Python 中的基础知识。

在我的项目中,我创建了一个摘要 class Execution,它定义了 Python 中不同类型的执行:

public abstract class Execution
{
    public enum ExecutionType
    {
        Affectation,
        Incrementation,
        Decrementation,
        Multiplier,
        Divisor,
        EntireDivisor,
        Modulo,
        IfStatement,
        ElseStatement,
        ForLoop,
        WhileLoop,
        Pass,  
    }
    
    public ExecutionType Type;

    public abstract string Representation();

    public Execution(ExecutionType type)
    {
        type = Type;
    }

    // Some others methods

}

这里是一个 class 的例子,它派生自 Execution :

public class Pass : Execution
{
    public Pass() : base(ExecutionType.Pass) { }

    public override string Representation()
    {
        return IndentRepresentation($"<color=#eb8f34>pass</color>");
    }
}

所有这些让我可以在另一个脚本中创建一个随机的 Python 代码生成器,所以我开始考虑一种允许生成 Python 代码的算法,该代码通过为每一行实例化来工作class 派生自 执行 class.

int randomIndex = 0; // Generated in the algorithm

List<Type> ExecutionsTypes = new List<Type>();
ExecutionsTypes.Add(typeof(Affectation)); // Error
ExecutionsTypes.Add(typeof(Pass));

Execution execution = (Execution)Activator.CreateInstance(ExecutionsTypes[randomIndex]); // Sometimes errors

我的问题是我想将这些 class 的所有类型存储在一个列表中,并能够通过浏览列表来实例化它们,但是,有些 class 是通用的 classes(所以我在那些地方有错误)但是其他人有必要的参数,并且由于选择是随机的,我不知道如何放置必要的参数。

为了使用Activator.CreateInstance(someType),每个类型都必须有一个无参数的构造函数。您指出有时会出现错误,因此很明显您的某些 classes 不会。即使他们这样做了,那也是一个困难的设计,因为稍后您可能想添加一个没有默认构造函数的类型,而您将无法做到。

一种方法是创建实例化的 classes 列表而不是类型列表。

而不是这个:

List<Type> executionsTypes = new List<Type>();
executionsTypes.Add(typeof(Affectation));
executionsTypes.Add(typeof(Pass));

这样做:

List<Execution> executions = new List<Execution>();
executions.Add(new Affectation()); 
executions.Add(new Pass());

然后,您可以 select 一个已经被实例化的 class 实例,而不是 select 从列表中创建一个类型并实例化它。

如果您不想重复使用 class 个实例并且每次都需要一个新实例怎么办?那么你可以这样做:

List<Func<Execution>> executions = new List<Func<Execution>>();
executions.Add(() => new Affectation()); 
executions.Add(() => new Pass());
executions.Add(() => new SomeTypeWithParameters("x", 1));

那么你从列表中 select 是一个 returns 和 Execution 的函数,你调用它来创建一个新实例。

Func<Execution> createExecutionFunction = // however you randomly select one
Execution execution = createExecutionFunction();