【发布时间】:2017-10-04 21:25:24
【问题描述】:
[编辑:我在这个问题中添加了很多细节,以便更清楚为什么我需要通过引用传递枚举器]
我正在编写一些代码来解析由命令和参数组成的列表。并非所有命令都具有相同数量的参数。例如,列表可以是 -
command1,
100,
command2,
54,
42,
71,
command3,
10,
31,
command1,
82,
command3,
102,
87
(请注意,某些命令可能具有非整数参数)
我正在使用 List 枚举器遍历数据列表。每个命令都有自己的类,能够从列表中解析命令的参数(并执行一系列与该命令相关的其他活动,这些活动在这个精简示例中不需要)。
我有一本字典,可以将命令连接到它们的类 -
var map = new Dictionary<string, Type>
{
{ "command1", typeof(Command1Class) },
{ "command2", typeof(Command2Class) },
{ "command3", typeof(Command3Class) },
};
所以我的基本解析循环如下-
var enumerator = data.GetEnumerator();
while (enumerator.MoveNext())
{
var command = (string)enumerator.Current;
codeBlock.AddBlock((Block)Activator.CreateInstance(map[command], new object[] { enumerator }));
}
(所有命令类都派生自相同的基类型,Block)
因此,在每个命令类的构造函数中,它可以解析该命令需要多少个参数,并且在返回主循环时,枚举器将继续遍历这些参数。
例如-
class Command1Class : Block
{
string param;
public Command1Class(ref List<object>.Enumerator enumerator)
{
enumerator.MoveNext();
param = (string)enumerator.Current;
}
}
但我发现枚举器仅在构造函数中本地修改。因此,在从构造函数返回时,枚举器仍然指向命令,而不是继续遍历该命令需要多少个参数。
如果我使用以下样式以非动态方式执行此操作,它会按预期工作,枚举器从构造函数返回时指向下一个命令 -
new SomeClass(ref enumerator)
所以我想知道为什么我的 CreateInstance 代码没有按预期工作,我如何能够动态地做到这一点?
【问题讨论】:
-
您到底希望发生什么?
-
不清楚“预期”是什么。
-
你们说的都对。我添加了更多信息,以使这样做的原因和预期结果更加清晰
-
Activator.CreateInstance 无法将
ref或out参数传递给构造函数,以使更改传播到外部。 动态地执行此操作的唯一方法是生成 IL 来执行此操作。但是,由于您也不能像这样动态调用此 IL,因此您需要对要构造的类型的构造函数参数进行标准化,以便可以将其包装在方法中。 -
@LasseV.Karlsen 我认为“Activator.CreateInstance 无法将 ref 或 out 参数传递给构造函数以使更改传播到外部”并不完全正确。您将所有参数作为
object[]数组传递,如果尊重的参数通过ref 或out 传递,则此数组中的元素将 更改。因此,变化将在外部可见,而不是以人们可能期望的方式。
标签: c# ref createinstance