如何存储子类类型并能够用列表的位置实例化一个变量?
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();
我正在 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();