次のコードをデバッグとしてコンパイルすると...
public class MyClass
{
private int myField;
public int MyProperty
{
get { return myField; }
set { myField = value; }
}
}
...一見役に立たない命令を含む奇妙なバイトコードがコンパイラによって生成されます。たとえば、プロパティのゲッター用に生成されるものを参照してください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
具体的には、そこで何nop
をしているのIL_0000
ですか?そして、なぜコンパイラは文字通りどこからともなくこの役に立たないbr.s
命令を生成するのでしょうか? IL_0008
一時的なローカル変数を作成するのはなぜCS$1$0000
ですか?
リリース構成の場合、命令セットは期待どおりに生成されます。
IL_0000: ldarg.0
IL_0001: ldfld int32 MSILTest.MyClass::myField
IL_0006: ret
編集
なぜブランチと一時的なローカル変数が別の質問にあるのかという質問に対する答えを見つけたと思います。おそらく、デバッグ中にブレークポイントを簡単に設定するためです。したがって、残っている問題は、nop
命令が生成される理由です。