このILフラグメント(MicrosoftのC#コンパイラによって生成されたもの)について考えてみます。
.class public sequential ansi sealed beforefieldinit Foo
extends [mscorlib]System.ValueType
{ … }
.method private hidebysig static void Main(string[] args) cil managed
{
.maxstack 1
.locals init ([0] valuetype Foo foo)
ldloca.s foo // ?
constrained. Foo // ?
callvirt instance string [mscorlib]System.Object::ToString() // ?
pop
ret
}
マークされた3行で何が起こっているのかを正確に知りたい// ?
:仮想メソッド(System.Object
's ToString
)がボックス化されていない値型で呼び出される可能性はありますか(CLI仕様のセクションI.8.9.7による))基本型はまったくありませんか?
私の現在の不完全な理解はこれです:
ldloca.s foo
結果として*
、ローカル変数foo
(タイプのボックス化されていない値を含む)への一時ポインター()が生成されますvaluetype Foo
。この場合、CLI仕様のセクションI.12.3.2.1に従って、マネージポインター(&
)が期待される場所で使用できます。この
*
ポインターは、メソッド呼び出しのthisポインターとして機能します。ここではマネージポインタ()として機能できるため、これは合法であるように見え&
ます。CLI標準では、セクションI.8.9.7でこの可能性について言及しています。constrained. Foo
プレフィックスはvaluetype Foo
、オブジェクトへの値のボックス化を防ぐためにありboxed Foo
ます。
しかし、主な問題は残っています。仮想メソッドを継承しないボックス化されていない値で仮想メソッドを呼び出すことができるのはなぜですか。