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) アセンブリ形式と、簡単なリファレンスの概要を示します。

形式 アセンブリ形式 説明
FE 16 <T> 制約。 thisType 型に制約されている型に対して仮想メソッドを呼び出します T

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

この時点での MSIL スタックの状態は、次のようにする必要があります。

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

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

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

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

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

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

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

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

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

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

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

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

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

適用対象