2

当我将以下代码编译为调试...

public class MyClass
{
    private int myField;

    public int MyProperty
    {
        get { return myField; }
        set { myField = value; }
    }
}

...编译器生成带有看似无用指令的奇怪字节码。例如,查看为属性的 getter 生成的内容MyProperty(用 反汇编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

具体来说,nopatIL_0000在那里做什么?为什么编译器会突然生成这条无用的br.s指令IL_0008?为什么它会创建临时局部变量CS$1$0000

对于发布配置,指令集按预期生成:

IL_0000:  ldarg.0
IL_0001:  ldfld      int32 MSILTest.MyClass::myField
IL_0006:  ret

编辑

我想我已经找到了一个问题的答案,为什么分支和临时局部变量存在于另一个问题中:这可能是为了在调试期间轻松设置断点。所以剩下的问题是为什么要生成nop指令。

4

1 回答 1

3

编译器创建这些操作码以提供更好的调试体验。在每个 c# 行的开头,编译器将引入 a nop以便调试器可以在那里中断。发出分支和临时局部变量,让您分析函数的返回值。

于 2016-01-13T11:18:08.423 回答