次の方法で共有


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

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

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

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

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

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

この最後のケースは、methodObjectValueType、または Enum で定義され、thisTypeによってオーバーライドされていない場合にのみ発生します。 この場合、ボックス化によって元のオブジェクトのコピーが作成されます。 ただし、オブジェクトの状態を変更 ObjectValueType、および 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 オペコードを使用できます。

適用対象