OpCodes.Constrained Campo

Definición

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

OpCode

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:

  1. Un puntero administrado, ptr, se inserta en la pila. El tipo de ptr debe ser un puntero administrado (&) a thisType. Tenga en cuenta que esto es diferente del caso de una instrucción sin prefijo callvirt , que espera una referencia de thisType.

  2. Los argumentos arg1 de método a través argN se insertan en la pila, al igual que con una instrucción sin prefijo callvirt .

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" al callvirt de method.

  • Si thisType es un tipo de valor e thisType implementa method , ptr se pasa sin modificar como puntero "this" a una call method instrucción para la implementación de method por thisType.

  • Si thisType es un tipo de valor y thisType no implementa method , ptr se desreferencia, se aplica la conversión boxeadora y se pasa como puntero "this" a la callvirt 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:

Se aplica a