OpCodes.Constrained OpCodes.Constrained OpCodes.Constrained OpCodes.Constrained Field

定義

仮想メソッド呼び出しをする対象の型を制約します。Constrains the type on which a virtual method call is made.

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) のアセンブリ形式と、簡単なリファレンスの概要を示しています。The following table lists the instruction's hexadecimal and Microsoft intermediate language (MSIL) assembly format, along with a brief reference summary:

形式Format アセンブリ形式Assembly Format 説明Description
FE 16 < T >FE 16 < T > 制約付き.constrained. thisType 型として制約されている型に対して仮想メソッドを呼び出します TCall a virtual method on a type constrained to be type T.

@No__t-0 プレフィックスは、callvirt 命令でのみ許可されます。The constrained prefix is permitted only on a callvirt instruction.

この時点での MSIL スタックの状態は、次のようにする必要があります。The state of the MSIL stack at this point must be as follows:

  1. マネージポインター (@no__t 0) がスタックにプッシュされます。A managed pointer, ptr, is pushed onto the stack. @No__t-0 の型は thisType へのマネージポインター (&) である必要があります。The type of ptr must be a managed pointer (&) to thisType. これは、プレフィックスのない callvirt 命令の場合とは異なり、thisType の参照が想定されていることに注意してください。Note that this is different from the case of an unprefixed callvirt instruction, which expects a reference of thisType.

  2. メソッド引数 arg1 から argN までは、プレフィックスが付けられていない callvirt 命令と同様にスタックにプッシュされます。Method arguments arg1 through argN are pushed onto the stack, just as with an unprefixed callvirt instruction.

@No__t 0 プレフィックスは、thisType が値型または参照型かどうかに関係なく、callvirt の命令を一貫した方法で作成できるように設計されています。The constrained prefix is designed to allow callvirt instructions to be made in a uniform way independent of whether thisType is a value type or a reference type.

@No__t 0 method 命令の先頭に constrained thisType が付いている場合、命令は次のように実行されます。When a callvirt method instruction has been prefixed by constrained thisType, the instruction is executed as follows:

  • @No__t-0 が (値型ではなく) 参照型の場合、ptr は逆参照され、' this ' ポインターとして method の @no__t に渡されます。If thisType is a reference type (as opposed to a value type) then ptr is dereferenced and passed as the 'this' pointer to the callvirt of method.

  • @No__t-0 が値の型で thisTypemethod を実装している場合、method による @no__t の実装では、call method 命令への ' this ' ポインターとして、ptr が未変更のまま渡されます。If thisType is a value type and thisType implements method then ptr is passed unmodified as the 'this' pointer to a call method instruction, for the implementation of method by thisType.

  • @No__t-0 が値の型で、thisTypemethod を実装していない場合、ptr は逆参照され、ボックス化され、callvirt method 命令への ' this ' ポインターとして渡されます。If thisType is a value type and thisType does not implement method then ptr is dereferenced, boxed, and passed as the 'this' pointer to the callvirt method instruction.

この最後のケースが発生するのは、methodObjectValueType、または Enum で定義されていて、thisType でオーバーライドされていない場合のみです。This last case can occur only when method was defined on Object, ValueType, or Enum and not overridden by thisType. この場合、ボックス化によって元のオブジェクトのコピーが作成されます。In this case, the boxing causes a copy of the original object to be made. ただし、ObjectValueTypeEnum のいずれのメソッドもオブジェクトの状態を変更しないため、このファクトを検出することはできません。However, because none of the methods of Object, ValueType, and Enum modify the state of the object, this fact cannot be detected.

@No__t 0 プレフィックスは、ジェネリックコードを作成する IL ジェネレーターをサポートしています。The constrained prefix supports IL generators that create generic code. 通常、callvirt 命令は、値型では有効ではありません。Normally the callvirt instruction is not valid on value types. 代わりに、IL コンパイラがコンパイル時に上記で説明した ' this ' 変換を効果的に実行する必要があります。 ptr の型と呼び出されるメソッドによって異なります。Instead it is required that IL compilers effectively perform the 'this' transformation outlined above at compile time, depending on the type of ptr and the method being called. ただし、ptr がコンパイル時に不明なジェネリック型の場合、コンパイル時にこの変換を行うことはできません。However, when ptr is a generic type that is unknown at compile time, it is not possible to make this transformation at compile time.

@No__t 0 オペコードを使用すると、IL コンパイラは、ptr が値型または参照型のどちらであるかに関係なく、同じ方法で仮想関数を呼び出すことができます。The constrained opcode allows IL compilers to make a call to a virtual function in a uniform way independent of whether ptr is a value type or a reference type. @No__t-0 がジェネリック型の変数であるケースを想定していますが、constrained のプレフィックスは非ジェネリック型でも機能し、値の型と参照の区別を隠す言語で仮想呼び出しを生成する複雑さを軽減できます。な.Although it is intended for the case where thisType is a generic type variable, the constrained prefix also works for nongeneric types and can reduce the complexity of generating virtual calls in languages that hide the distinction between value types and reference types.

@No__t-0 プレフィックスを使用すると、値型のバージョン管理に関する潜在的な問題を回避することもできます。Using the constrained prefix also avoids potential versioning problems with value types. @No__t-0 プレフィックスが使用されていない場合は、値型によって System.object のメソッドがオーバーライドされるかどうかに応じて、異なる IL を生成する必要があります。If the constrained prefix is not used, different IL must be emitted depending on whether or not a value type overrides a method of System.Object. たとえば、値型 V がオブジェクトの ToString () メソッドをオーバーライドした場合、call V.ToString() 命令が生成されます。そうでない場合は、@no__t 3 命令と callvirt Object.ToString() 命令が生成されます。For example, if a value type V overrides the Object.ToString() method, a call V.ToString() instruction is emitted; if it does not, a box instruction and a callvirt Object.ToString() instruction are emitted. 前のケースでは、オーバーライドが後で削除された場合は、バージョン管理の問題が発生する可能性があります。後者の場合は、オーバーライドが後で追加されます。A versioning problem can arise in the former case if the override is later removed, and in the latter case if an override is later added.

@No__t-0 プレフィックスは、値型のインターフェイスメソッドを呼び出すためにも使用できます。これは、インターフェイスメソッドを実装する値型のメソッドを MethodImpl を使用して変更できるためです。The constrained prefix can also be used for invocation of interface methods on value types, because the value type method implementing the interface method can be changed using a MethodImpl. @No__t-0 プレフィックスが使用されていない場合、コンパイラはコンパイル時にバインドする値型のメソッドを強制的に選択します。If the constrained prefix is not used, the compiler is forced to choose which of the value type's methods to bind to at compile time. @No__t-0 プレフィックスを使用すると、コンパイル時ではなく、実行時にインターフェイスメソッドを実装するメソッドに MSIL をバインドできます。Using the constrained prefix allows the MSIL to bind to the method that implements the interface method at run time, rather than at compile time.

次の Emit メソッドオーバーロードは、constrained オペコードを使用できます。The following Emit method overload can use the constrained opcode:

  • ILGenerator (オペコード, Type)ILGenerator.Emit(OpCode, Type)

適用対象