OpCodes.Constrained フィールド
定義
重要
一部の情報は、リリース前に大きく変更される可能性があるプレリリースされた製品に関するものです。 Microsoft は、ここに記載されている情報について、明示または黙示を問わず、一切保証しません。
仮想メソッド呼び出しが行われる型を制約します。
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 スタックの状態は次のようになります。
マネージド ポインター (
ptr) がスタックにプッシュされます。ptrの型は、thisTypeするマネージド ポインター (&) である必要があります。 これは、thisTypeの参照を想定する未修正のcallvirt命令の場合とは異なっています。argNを介してarg1メソッド引数は、未修正のcallvirt命令と同様にスタックにプッシュされます。
constrained プレフィックスは、thisType が値型か参照型かに関係なく、一様な方法で callvirt 命令を行えるように設計されています。
callvirt
method 命令の前に constrainedthisTypeが付いている場合、命令は次のように実行されます。
thisTypeが (値型ではなく) 参照型である場合、ptrは逆参照され、methodのcallvirtへの 'this' ポインターとして渡されます。thisTypeが値型であり、thisTypemethod実装している場合、ptrは、thisTypeによるmethodの実装のために、callmethod命令への '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 オペコードを使用できます。