Language

OpCodes.Constrained フィールド

定義

仮想メソッド呼び出しが行われる型を制約します。

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

フィールド値

注釈

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

フォーマット アセンブリ形式 Description
FE 16 <T> 制約。 thisType T型に制限された型に対して仮想メソッドを呼び出します。

constrained プレフィックスは、callvirt命令でのみ許可されます。

この時点での MSIL スタックの状態は次のようになります。

  1. マネージド ポインター ( ptr) がスタックにプッシュされます。 ptrの型は、&するマネージド ポインター (thisType) である必要があります。 これは、callvirtの参照を想定する未修正のthisType命令の場合とは異なされることに注意してください。

  2. arg1を介してargNメソッド引数は、未修正のcallvirt命令と同様にスタックにプッシュされます。

constrained プレフィックスは、callvirtが値型か参照型かに関係なく、一様な方法でthisType命令を行えるように設計されています。

callvirt method命令の前に constrainedthisType が付いている場合、命令は次のように実行されます。

  • thisTypeが (値型ではなく) 参照型の場合、ptrは逆参照され、callvirtのmethodへの 'this' ポインターとして渡されます。

  • thisTypeが値型であり、thisTypeがmethod実装する場合、ptrは、callによるmethodの実装のために、methodthisType命令への 'this' ポインターとして変更されていない状態で渡されます。

  • thisTypeが値型であり、thisTypeがmethodを実装していない場合、ptrは逆参照され、ボックス化され、callvirtmethod命令への 'this' ポインターとして渡されます。

この最後のケースは、 method が Object、 ValueType、または Enum で定義され、 thisTypeによってオーバーライドされていない場合にのみ発生します。 この場合、ボックス化によって元のオブジェクトのコピーが作成されます。 ただし、オブジェクトの状態を変更 Object、 ValueType、 Enum のいずれの方法もないため、この事実は検出できません。

constrained プレフィックスは、汎用コードを作成する IL ジェネレーターをサポートします。 通常、 callvirt 命令は値型では無効です。 代わりに、IL コンパイラは、 ptr の種類と呼び出されるメソッドに応じて、コンパイル時に上記の 'this' 変換を効果的に実行する必要があります。 ただし、 ptr がコンパイル時に不明なジェネリック型である場合、コンパイル時にこの変換を実行することはできません。

constrainedオペコードを使用すると、IL コンパイラは、ptrが値型か参照型かに関係なく、一様な方法で仮想関数を呼び出すことができます。 thisTypeがジェネリック型変数である場合を想定していますが、constrained プレフィックスは非ジェネリック型でも機能し、値型と参照型の区別を隠す言語での仮想呼び出しの生成の複雑さを軽減できます。

constrained プレフィックスを使用すると、値型に関する潜在的なバージョン管理の問題を回避することもできます。 constrained プレフィックスを使用しない場合は、値型が System.Object のメソッドをオーバーライドするかどうかに応じて、異なる IL を出力する必要があります。 たとえば、値型 V が Object.ToString() メソッドをオーバーライドすると、 callV.ToString() 命令が出力されます。そうでない場合は、 box 命令と callvirtObject.ToString() 命令が出力されます。 バージョン管理の問題は、オーバーライドが後で削除された場合は前のケースで発生し、後者の場合はオーバーライドが後で追加される場合に発生する可能性があります。

constrained プレフィックスは、MethodImplを使用してインターフェイス メソッドを実装する値型メソッドを変更できるため、値型のインターフェイス メソッドの呼び出しにも使用できます。 constrained プレフィックスが使用されていない場合、コンパイラは、コンパイル時にバインドする値型のメソッドを強制的に選択します。 constrained プレフィックスを使用すると、MSIL はコンパイル時ではなく、実行時にインターフェイス メソッドを実装するメソッドにバインドできます。

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

適用対象