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 a 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 y lenguaje intermedio de Microsoft (MSIL), junto con un breve resumen de referencia:
Formato | Formato de ensamblado | Descripción |
---|---|---|
FE 16 < T > |
Limitada. thisType |
Llame a un método virtual en un tipo restringido para que sea de tipo T . |
El constrained
prefijo solo se permite en una callvirt
instrucción .
El estado de la pila MSIL en este momento debe ser el siguiente:
Un puntero administrado,
ptr
, se inserta en la pila. El tipo deptr
debe ser un puntero administrado (&
) athisType
. Tenga en cuenta que esto es diferente del caso de una instrucción sin prefijocallvirt
, que espera una referencia dethisType
.Los argumentos
arg1
de método a travésargN
se insertan en la pila, al igual que con una instrucción sin prefijocallvirt
.
El constrained
prefijo está diseñado para permitir callvirt
que las instrucciones se realicen de forma uniforme independientemente de si thisType
es un tipo de valor o un tipo de referencia.
Cuando una callvirt
method
instrucción tiene el prefijo constrained
thisType
, 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 ethisType
implementamethod
,ptr
se pasa sin modificar como puntero "this" a unacall
method
instrucción para la implementación demethod
porthisType
.Si
thisType
es un tipo de valor ythisType
no implementamethod
,ptr
se desreferencia, se aplica la conversión boxeadora y se pasa como puntero "this" a lacallvirt
method
instrucción .
Este último caso solo se puede producir cuando method
se definió en Object, ValueTypeo Enum y no se invalidó por 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 modifica el estado del objeto , este hecho no se puede detectar.
El constrained
prefijo admite generadores de IL que crean código genérico. Normalmente, la callvirt
instrucción 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 thisType
el que es una variable de tipo genérico, el constrained
prefijo 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 constrained
prefijo también evita posibles problemas de control de versiones con tipos de valor. Si no se usa el constrained
prefijo, se debe emitir un 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 V
de valor invalida el método Object.ToString(), se emite una call
V.ToString()
instrucción; si no es así, se emite una box
instrucción y una callvirt
Object.ToString()
instrucción. 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 constrained
prefijo también se puede usar para la invocación de 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 .MethodImpl
Si no se usa el constrained
prefijo, el compilador se ve obligado a elegir a qué métodos del tipo de valor se enlazarán en tiempo de compilación. El uso del constrained
prefijo 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 sobrecarga del método siguiente Emit puede usar el constrained
código de operación: