なぜこれが起きているのか不思議です。次のコード例を読んでください、各セクションの下のコメントに放出された対応するIL:コンパイラは、第二のセクションの最初のセクションが、call
ためcallvirt
を発するなぜC#コンパイラがGetType()メソッド呼び出しのcallvirt命令を発行するのはなぜですか?
using System;
class Program
{
static void Main()
{
Object o = new Object();
o.GetType();
// L_0001: newobj instance void [mscorlib]System.Object::.ctor()
// L_0006: stloc.0
// L_0007: ldloc.0
// L_0008: callvirt instance class [mscorlib]System.Type [mscorlib]System.Object::GetType()
new Object().GetType();
// L_000e: newobj instance void [mscorlib]System.Object::.ctor()
// L_0013: call instance class [mscorlib]System.Type [mscorlib]System.Object::GetType()
}
}
?コンパイラが非仮想メソッドのcallvirt
命令を発行する理由はありますか?コンパイラが非仮想メソッドのためにcallvirt
を発行するケースがあると、型安全性に問題が生じますか?
非常に良い質問...私は自分の書籍に手を差し伸べました。 – Gishu
集計:ケース(1)仮想メソッドを呼び出す:callvirtを生成します。ケース(2)null可能な受信側でインスタンスメソッドを呼び出す:安価なヌルチェックを得るためにcallvirtを生成する - はい、これは型保証されています。ケース(3)既知のヌル可能でない受信側でインスタンスメソッドを呼び出す:_avoid_nullチェックの呼び出しを生成する。最初の例はカテゴリ(2)に分類され、2番目の例はカテゴリ(3)に分類されます。コンパイラは、newが決してnullを返さないことを知っているので、再度チェックする必要はありません。 –
Ericのおかげで、ヌルチェックは意味があります。あなたのコメントと紀州の答えは物事をもっとはっきりさせます! :) –