3

我正在尝试发出我认为是一个简单的对象数组的内容,该数组会产生类似于以下示例的代码

object[] parameters = new object[] { a, b, };

当我使用 VS 在 C# 中编写上述代码时,我得到以下 IL。正如预期的那样,这有效。

.locals init (
[0] object[] parameters,
[1] object[] CS$0$0000)

但是,当我尝试直接 Emit IL 时,我只会得到一个单索引 init 数组。有人可以帮我告诉我这里哪里出错了吗?

这是我正在使用的发射代码:

int arraySize = 2;
LocalBuilder paramValues = ilGenerator.DeclareLocal(typeof(object[]));
paramValues.SetLocalSymInfo("parameters");
ilGenerator.Emit(OpCodes.Ldc_I4_S, arraySize);
ilGenerator.Emit(OpCodes.Newarr, typeof(object));
ilGenerator.Emit(OpCodes.Stloc, paramValues);

这是生成的 IL:

.locals init (
[0] object[] objArray)

生成的 IL 的其余部分在两个解决方案之间是相同的,但由于某种原因,.locals init是不同的。

4

3 回答 3

3

C# 编译器生成如下代码:

object[] temp = new object[2];
temp[0] = (object)a;
temp[1] = (object)b;
parameters = temp;

temp 变量是您看到的 CS$0$0000。我认为这样做是为了确保在初始化数组时可能引发的异常不会在“参数”中留下部分初始化的数组。当代码捕获异常时,这可能会导致意外失败。如所写,命名变量为空或完全初始化。好主意。

于 2010-04-04T15:23:13.643 回答
0

如果您只声明一个本地 ( paramValues),那么只会声明一个本地。DeclareLocal如果您需要第二个本地人,请再次致电。但我不明白你为什么需要这个?声明不需要的本地人是没有意义的。

于 2010-04-04T11:43:10.010 回答
0

变量在这里CS$0$0000是因为编译器没有优化变量的创建/使用。它将这个自动创建的变量用于new object[] { a, b, }部分代码,然后将创建的对象分配给该object[] parameters变量。这种行为主要是因为 IL 的基于堆栈的性质。尝试在发布模式下运行代码,看看它是否得到优化。

于 2010-04-04T11:50:39.450 回答