C# 経由で CLR から引用すると、CLR 経由call
で実行時に基本型によって定義されたメソッドを検索するかのように読み取れます。
次に、
call
IL 命令を使用してインスタンスまたは仮想メソッドを呼び出します。オブジェクトを参照する変数を指定する必要があります。変数自体の型は、CLR が呼び出す必要があるメソッドを定義する型を示します。変数の型がメソッドを定義していない場合は、基本型が一致するメソッドについてチェックされます。
と
非仮想インスタンス メソッドを呼び出す場合、JIT は、呼び出しに使用されている変数の型に対応する型オブジェクトを見つけます。呼び出されるメソッドが型で定義されていない場合、JIT はクラス階層を下って Object に向かってこのメソッドを探します。これを行うことができるのは、各型オブジェクトにその基本型を参照するフィールドがあるためです。次に、JIT は、呼び出されているメソッドを参照する型オブジェクトのメソッド テーブル内のエントリを見つけます。
ただし、次の例に基づくと、メソッドの継承はコンパイル時にチェックされるようです。
class A
{
public void Foo() {}
}
class B : A {}
void Main()
{
new B().Foo();
}
IL_0000: newobj UserQuery+B..ctor
IL_0005: call UserQuery+A.Foo // Not B.Foo, resolved by C# complier.
私は正しいですか?
私がこれをしても:
void Main()
{
B x = new B();
x.Foo();
}
IL_0000: newobj UserQuery+B..ctor
IL_0005: stloc.0 // x
IL_0006: ldloc.0 // x
IL_0007: callvirt UserQuery+A.Foo // Not B.Foo, resolved by C# complier.
アップデート:
これで、解像度が静的であることがわかりました。
そして、JIT が必要とする変数の型は、実際にはメタデータ トークンによって指定されたクラスであると私は信じています。
重複アラート
実際には、非仮想メソッド呼び出しの内部を説明するときに Is Richter wrong? と重複しています。
私と同じ質問をした人がもう一人いてよかったです。