OpCodes.Callvirt フィールド

定義

オブジェクト上で遅延バインディング メソッドを呼び出し、戻り値を評価スタックにプッシュします。

public: static initonly System::Reflection::Emit::OpCode Callvirt;
public static readonly System.Reflection.Emit.OpCode Callvirt;
 staticval mutable Callvirt : System.Reflection.Emit.OpCode
Public Shared ReadOnly Callvirt As OpCode 

フィールド値

注釈

次の表に、命令の 16 進数と Microsoft Intermediate Language (MSIL) アセンブリ形式と、簡単なリファレンスの概要を示します。

形式 アセンブリ形式 説明
6f <T> Callvirt method に関連付けられている特定のメソッドを obj呼び出します。

スタック遷移の動作は、順番に次のようになります。

  1. オブジェクト参照 obj がスタックにプッシュされます。

  2. メソッド引数 arg1 がスタック argN にプッシュされます。

  3. メソッドの引数 arg1argN オブジェクト参照 obj がスタックからポップされます。メソッド呼び出しは、これらの引数を使用して実行され、メソッド メタデータ トークンによって obj 参照される メソッドに制御が転送されます。 完了すると、戻り値が呼び出し先メソッドによって生成され、呼び出し元に送信されます。

  4. 戻り値がスタックにプッシュされます。

命令は callvirt 、オブジェクトに対して遅延バインディング メソッドを呼び出します。 つまり、 メソッドは、メソッド ポインターに表示されるコンパイル時クラスではなく、 のランタイム型 obj に基づいて選択されます。 Callvirt を使用して、仮想メソッドとインスタンス メソッドの両方を呼び出すことができます。 命令のcallvirt直前に (Tailcall) プレフィックスをtail付けて、制御を転送する前に現在のスタック フレームを解放するように指定できます。 呼び出しが元のメソッドよりも高い信頼のメソッドに制御を転送する場合、スタック フレームは解放されません。

メソッド メタデータ トークンは、呼び出すメソッドの名前、クラス、およびシグネチャを提供します。 に obj 関連付けられているクラスは、それがインスタンスであるクラスです。 クラスで、指定されたメソッド名とシグネチャに一致する非静的メソッドが定義されている場合、このメソッドが呼び出されます。 それ以外の場合は、このクラスの基底クラス チェーン内のすべてのクラスが順番にチェックされます。 メソッドが見つからない場合はエラーです。

Callvirt メソッドを呼び出す前に、オブジェクトと関連する引数を評価スタックからポップします。 メソッドに戻り値がある場合、メソッドの完了時にスタックにプッシュされます。 呼び出し先側では、 obj パラメーターは引数 0、 arg1 引数 1 などとしてアクセスされます。

引数は、左から右の順序でスタックに配置されます。 つまり、最初の引数が計算され、スタックに配置され、次に 2 番目の引数、次に 3 番目の引数が、必要なすべての引数が降順でスタックの上に配置されます。 インスタンス参照 obj (常に に callvirt必要) は、ユーザーが参照できる引数の前にプッシュする必要があります。 シグネチャ (メタデータ トークンに含まれる) には、このポインターのパラメーター リストにエントリを含める必要はありません。

仮想メソッドは、 命令を使用して Call 呼び出すこともできます。

MissingMethodException は、指定された名前とシグネチャを持つ非静的メソッドが、 またはその基底クラスに関連付けられている obj クラスで見つからなかった場合にスローされます。 これは通常、Microsoft Intermediate Language (MSIL) 命令が実行時ではなくネイティブ コードに変換されるときに検出されます。

NullReferenceException obj が null の場合は がスローされます。

SecurityException は、呼び出されたメソッドへのアクセス権が呼び出し元にシステム セキュリティによって付与されない場合にスローされます。 セキュリティ チェックは、CIL が実行時ではなくネイティブ コードに変換されるときに発生する可能性があります。

Note

値型で System.Object のメソッドを呼び出す場合は、 命令でcallvirtプレフィックスをconstrained使用することを検討してください。 これにより、値の型がメソッドをオーバーライドするかどうかに応じて異なる IL を出力する必要がなくなります。これにより、バージョン管理の問題が回避されます。 インターフェイス メソッドを constrained 実装する値型メソッドは を使用して変更できるため、値型でインターフェイス メソッドを呼び出すときはプレフィックスを使用 MethodImplすることを検討してください。 これらの問題については、オペコードで Constrained 詳しく説明されています。

Emit のメソッド オーバーロードでは、オペコードを callvirt 使用できます。

適用対象