我正在尝试使用Reflection& amp;生成动态装配。在.NET中发出。我收到一个错误,“Common Language Runtime检测到一个无效的程序。”我创建了另一个程序,它具有我想要的功能,使用硬编码类型。我试图编写的功能最终将使用动态类型,但我可以使用ILDasm来查看我需要生成的IL。我正在将我生成的IL与编译器生成的IL进行比较。在一个方法的.locals init声明中,我看到编译器生成的代码中有一个额外的项,
编译生成:
.locals init ([0] class [System.Core]System.Linq.Expressions.ParameterExpression CS$0$0000,
[1] class [System.Core]System.Linq.Expressions.ParameterExpression[] CS$0$0001)
我的:
.locals init (class [System.Core]System.Linq.Expressions.ParameterExpression V_0,
class [System.Core]System.Linq.Expressions.ParameterExpression[] V_1)
我不理解编译器生成的代码中“[0]”和“[1]”的重要性。谁能告诉我这是什么意思?
作为一个更普遍的问题,我可以毫不费力地遵循大多数ILDasm输出。但我经常遇到一个有问题的表达。例如,在ILDasm的这一行
callvirt instance class [EntityFramework]System.Data.Entity.ModelConfiguration.EntityTypeConfiguration`1<!!0> [EntityFramework]System.Data.Entity.DbModelBuilder::Entity<class DynamicEdmxTrial.HardFooAsset>()
“!! 0”可能是指Entity&lt;&gt;的泛型类型,但我不确定,我想知道ILDasm输出是否有一个键可以解释其更加模糊的输出我
答案 0 :(得分:1)
该规范免费提供here。它需要一点点习惯,但一旦你弄清楚结构,很容易找到大部分细节。
!!
列在 II.7.1类型:
Type ::= | Description | Clause ‘!’ Int32 | Generic parameter in a type definition, | §II.9.1 | accessed by index from 0 | | ‘!!’ Int32 | Generic parameter in a method | §II.9.2 | definition, accessed by index from 0 | ...
换句话说,在C#调用f<T, U>()
的方法中,!!0
为T
,!!1
为U
。
然而,[0]
是一个很好的问题。该规范似乎没有解决它。 II.15.4.1.3 .locals指令中描述了.locals
指令,该指令将语法列为
MethodBodyItem ::= ... | .locals [ init ] ‘(’ LocalsSignature ‘)’ LocalsSignature ::= Local [ ‘,’ Local ]* Local ::= Type [ Id ]
除非它是[0]
的一部分,否则似乎没有任何内容允许Type
,Type
不允许任何以[
开头的内容。我的猜测是,这是一个特定于Microsoft实现的无证特性,旨在帮助人类读者看到位置0是局部变量CS$0$0000
,以便生成的指令通过索引访问局部变量。
试验ILAsm表明这正是它的意思。采用简单的C#程序:
static class Program {
static void Main() {
int i = 0, j = 1;
}
}
并编译然后将其反汇编(csc test.cs && ildasm /text test.exe >test.il
)显示:
....
.locals init (int32 V_0,
int32 V_1)
IL_0000: nop
IL_0001: ldc.i4.0
IL_0002: stloc.0
IL_0003: ldc.i4.1
IL_0004: stloc.1
IL_0005: ret
....
将.locals
修改为
.locals init ([0] int32 V_0, [0] int32 V_1)
提供了一条有用的警告信息:
test.il(41) : warning : Local var slot 0 is in use
确实,声明不同类型的变量,然后使用[2]
,[1]
,[0]
对它们进行重新排序,汇编并立即反汇编结果,表明变量已重新排序。