OpCodes.Constrained Campo
Definição
Importante
Algumas informações se referem a produtos de pré-lançamento que podem ser substancialmente modificados antes do lançamento. A Microsoft não oferece garantias, expressas ou implícitas, das informações aqui fornecidas.
Restringe o tipo no qual uma chamada de método virtual é feita.
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 do campo
Comentários
A tabela a seguir lista o formato de assembly hexadecimal e de linguagem intermediária da Microsoft (MSIL) da instrução, juntamente com um breve resumo de referência:
| Formato | Formato de assembly | Descrição |
|---|---|---|
FE 16 <T> |
Restrita. thisType |
Chame um método virtual em um tipo restrito para ser tipo T. |
O prefixo constrained é permitido apenas em uma instrução callvirt.
O estado da pilha MSIL neste ponto deve ser o seguinte:
Um ponteiro gerenciado,
ptr, é empurrado para a pilha. O tipo deptrdeve ser um ponteiro gerenciado (&) parathisType. Observe que isso é diferente do caso de uma instrução decallvirtnão prefixada, que espera uma referência dethisType.Os argumentos de método
arg1por meio deargNsão enviados por push para a pilha, assim como com uma instrução decallvirtnão prefixada.
O prefixo constrained foi projetado para permitir que callvirt instruções sejam feitas de forma uniforme, independentemente de thisType seja um tipo de valor ou um tipo de referência.
Quando uma instrução callvirtmethod foi prefixada por constrainedthisType, a instrução é executada da seguinte maneira:
Se
thisTypefor um tipo de referência (em vez de um tipo de valor),ptrserá desreferenciado e passado como o ponteiro 'this' para ocallvirtdemethod.Se
thisTypefor um tipo de valor ethisTypeimplementarmethod,ptrserá passado sem modificação como o ponteiro 'this' para uma instruçãocallmethod, para a implementação demethodporthisType.Se
thisTypefor um tipo de valor ethisTypenão implementarmethodptrserá desreferenciado, em caixa e passado como o ponteiro 'this' para a instruçãocallvirtmethod.
Esse último caso só pode ocorrer quando method foi definido em Object, ValueTypeou Enum e não substituído por thisType. Nesse caso, o boxing faz com que uma cópia do objeto original seja feita. No entanto, como nenhum dos métodos de Object, ValueTypee Enum modificar o estado do objeto, esse fato não pode ser detectado.
O prefixo constrained dá suporte a geradores IL que criam código genérico. Normalmente, a instrução callvirt não é válida em tipos de valor. Em vez disso, é necessário que os compiladores IL executem efetivamente a transformação 'this' descrita acima no tempo de compilação, dependendo do tipo de ptr e do método que está sendo chamado. No entanto, quando ptr é um tipo genérico desconhecido em tempo de compilação, não é possível fazer essa transformação em tempo de compilação.
O opcode constrained permite que os compiladores IL façam uma chamada para uma função virtual de forma uniforme, independentemente de ptr seja um tipo de valor ou um tipo de referência. Embora se destine ao caso em que thisType é uma variável de tipo genérico, o prefixo constrained também funciona para tipos não genéricos e pode reduzir a complexidade da geração de chamadas virtuais em linguagens que ocultam a distinção entre tipos de valor e tipos de referência.
Usar o prefixo constrained também evita possíveis problemas de controle de versão com tipos de valor. Se o prefixo constrained não for usado, il diferente deverá ser emitido dependendo se um tipo de valor substitui ou não um método de System.Object. Por exemplo, se um tipo de valor V substituir o método Object.ToString(), uma instrução callV.ToString() será emitida; se isso não acontecer, uma instrução box e uma instrução callvirtObject.ToString() serão emitidas. Um problema de controle de versão poderá surgir no caso anterior se a substituição for removida posteriormente e, no último caso, se uma substituição for adicionada posteriormente.
O prefixo constrained também pode ser usado para invocação de métodos de interface em tipos de valor, pois o método de tipo de valor que implementa o método de interface pode ser alterado usando um MethodImpl. Se o prefixo constrained não for usado, o compilador será forçado a escolher a qual dos métodos do tipo de valor associar em tempo de compilação. Usar o prefixo constrained permite que o MSIL se associe ao método que implementa o método de interface em tempo de execução, em vez de em tempo de compilação.
A seguinte sobrecarga do método Emit pode usar o constrained opcode: