当我将以下代码编译为debug ...
时public class MyClass
{
private int myField;
public int MyProperty
{
get { return myField; }
set { myField = value; }
}
}
...编译器会产生看似无用的奇怪字节码。例如,查看为属性MyProperty
的getter生成的内容(用ildasm.exe
反汇编):
.method public hidebysig specialname instance int32
get_MyProperty() cil managed
{
// Code size 12 (0xc)
.maxstack 1
.locals init ([0] int32 CS$1$0000)
IL_0000: nop
IL_0001: ldarg.0
IL_0002: ldfld int32 MSILTest.MyClass::myField
IL_0007: stloc.0
IL_0008: br.s IL_000a
IL_000a: ldloc.0
IL_000b: ret
} // end of method MyClass::get_MyProperty
具体来说,nop
IL_0000
在那里做什么?为什么编译器在br.s
无处不在地生成这个无用的IL_0008
指令?为什么要创建临时局部变量CS$1$0000
?
对于发布配置,指令集按预期生成:
IL_0000: ldarg.0
IL_0001: ldfld int32 MSILTest.MyClass::myField
IL_0006: ret
修改
我想我已经找到了一个问题的答案,为什么分支和临时局部变量存在于different question中:它可能很容易在调试期间设置断点。所以仍然存在的问题是为什么nop
指令得到了治疗。
答案 0 :(得分:3)
编译器创建这些操作码以提供更好的调试体验。在每个c#行的开头,编译器将引入一个
nop
所以调试器可以在那里打破。发出分支和临时局部变量,以便分析函数返回值。