OpCodes.Constrained Campo
Definición
Importante
Parte de la información hace referencia a la versión preliminar del producto, que puede haberse modificado sustancialmente antes de lanzar la versión definitiva. Microsoft no otorga ninguna garantía, explícita o implícita, con respecto a la información proporcionada aquí.
Restringe el tipo en el que se realiza una llamada de método virtual.
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
Valor de campo
Comentarios
En la tabla siguiente se muestra el formato de ensamblado hexadecimal de la instrucción y del lenguaje intermedio de Microsoft (MSIL), junto con un breve resumen de referencia:
Formato | Formato de ensamblado | Descripción |
---|---|---|
FE 16 <T > |
encogido. thisType |
Llame a un método virtual en un tipo restringido para que sea de tipo T . |
El prefijo constrained
solo se permite en una instrucción callvirt
.
El estado de la pila MSIL en este punto debe ser el siguiente:
Un puntero administrado,
ptr
, se inserta en la pila. El tipo deptr
debe ser un puntero administrado (&
) parathisType
. Tenga en cuenta que esto es diferente del caso de una instruccióncallvirt
sin prefijo, que espera una referencia dethisType
.Los argumentos de método
arg1
a través deargN
se insertan en la pila, al igual que con una instruccióncallvirt
sin prefijo.
El prefijo constrained
está diseñado para permitir que callvirt
instrucciones se realicen de forma uniforme independientemente de si thisType
es un tipo de valor o un tipo de referencia.
Cuando constrained
thisType
ha prefijo una instrucción callvirt
method
, la instrucción se ejecuta de la siguiente manera:
Si
thisType
es un tipo de referencia (en lugar de un tipo de valor),ptr
se desreferencia y se pasa como puntero "this" alcallvirt
demethod
.Si
thisType
es un tipo de valor ythisType
implementamethod
,ptr
se pasa sin modificar como puntero "this" a una instruccióncall
method
, para la implementación demethod
mediantethisType
.Si
thisType
es un tipo de valor ythisType
no implementamethod
,ptr
se desreferencia, boxed y se pasa como puntero "this" a la instruccióncallvirt
method
.
Este último caso solo puede producirse cuando method
se definió en Object, ValueTypeo Enum y no se invalidó thisType
. En este caso, la conversión boxing hace que se realice una copia del objeto original. Sin embargo, dado que ninguno de los métodos de Object, ValueTypey Enum modificar el estado del objeto, no se puede detectar este hecho.
El prefijo constrained
admite generadores de IL que crean código genérico. Normalmente, la instrucción callvirt
no es válida en los tipos de valor. En su lugar, es necesario que los compiladores de IL realicen eficazmente la transformación "this" descrita anteriormente en tiempo de compilación, según el tipo de ptr
y el método al que se llama. Sin embargo, cuando ptr
es un tipo genérico desconocido en tiempo de compilación, no es posible realizar esta transformación en tiempo de compilación.
El constrained
código de operación permite a los compiladores de IL realizar una llamada a una función virtual de forma uniforme independientemente de si ptr
es un tipo de valor o un tipo de referencia. Aunque está pensado para el caso en el que thisType
es una variable de tipo genérico, el prefijo constrained
también funciona para tipos no genéricos y puede reducir la complejidad de generar llamadas virtuales en lenguajes que ocultan la distinción entre los tipos de valor y los tipos de referencia.
El uso del prefijo constrained
también evita posibles problemas de control de versiones con tipos de valor. Si no se usa el prefijo constrained
, se debe emitir una IL diferente en función de si un tipo de valor invalida o no un método de System.Object. Por ejemplo, si un tipo de valor V
invalida el método Object.ToString(), se emite una instrucción call
V.ToString()
; si no es así, se emiten una instrucción box
y una instrucción callvirt
Object.ToString()
. Puede surgir un problema de control de versiones en el caso anterior si la invalidación se quita más adelante y, en este último caso, si se agrega una invalidación más adelante.
El prefijo constrained
también se puede usar para invocar métodos de interfaz en tipos de valor, ya que el método de tipo de valor que implementa el método de interfaz se puede cambiar mediante un MethodImpl
. Si no se usa el prefijo constrained
, el compilador se ve obligado a elegir a cuál de los métodos del tipo de valor se enlazan en tiempo de compilación. El uso del prefijo constrained
permite que el MSIL se enlace al método que implementa el método de interfaz en tiempo de ejecución, en lugar de en tiempo de compilación.
La siguiente sobrecarga del método Emit puede usar el código de operación constrained
: