OpCodes.Callvirt 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.
Chama um método de associação tardia em um objeto, enviando o valor retornado por push para a pilha de avaliação.
public: static initonly System::Reflection::Emit::OpCode Callvirt;
public static readonly System.Reflection.Emit.OpCode Callvirt;
staticval mutable Callvirt : System.Reflection.Emit.OpCode
Public Shared ReadOnly Callvirt As OpCode
Valor do campo
Comentários
A tabela a seguir lista o formato de assembly hexadecimal e MSIL (Microsoft Intermediate Language) da instrução, juntamente com um breve resumo de referência:
Formatar | Formato de assembly | Descrição |
---|---|---|
6F <T > |
Callvirt method |
Chama um método específico associado obj a . |
O comportamento de transição da pilha, em ordem sequencial, é:
Uma referência
obj
de objeto é enviada por push para a pilha.Os argumentos de método são
argN
enviadosarg1
por push para a pilha.Os argumentos
arg1
de método por meioargN
de e a referênciaobj
de objeto são exibidos da pilha; a chamada de método é executada com esses argumentos e o controle é transferido para o método emobj
referenciado pelo token de metadados do método. Quando concluído, um valor retornado é gerado pelo método chamador e enviado ao chamador.O valor retornado é enviado por push para a pilha.
A callvirt
instrução chama um método de associação tardia em um objeto . Ou seja, o método é escolhido com base no tipo de runtime de obj
em vez da classe de tempo de compilação visível no ponteiro do método.
Callvirt
pode ser usado para chamar métodos virtuais e de instância. A callvirt
instrução pode ser imediatamente precedida por um tail
prefixo (Tailcall) para especificar que o quadro de pilha atual deve ser liberado antes de transferir o controle. Se a chamada transferir o controle para um método de confiança mais alta do que o método original, o quadro de pilha não será liberado.
O token de metadados do método fornece o nome, a classe e a assinatura do método a ser chamado. A classe associada obj
a é a classe da qual ela é uma instância. Se a classe definir um método não estático que corresponda ao nome e à assinatura do método indicados, esse método será chamado. Caso contrário, todas as classes na cadeia de classes base dessa classe serão verificadas em ordem. É um erro se nenhum método for encontrado.
Callvirt
exibe o objeto e os argumentos associados da pilha de avaliação antes de chamar o método . Se o método tiver um valor retornado, ele será enviado por push na pilha após a conclusão do método. No lado do receptor, o obj
parâmetro é acessado como argumento 0, arg1
como argumento 1 e assim por diante.
Os argumentos são colocados na pilha na ordem da esquerda para a direita. Ou seja, o primeiro argumento é calculado e colocado na pilha, depois o segundo argumento, depois o terceiro, até que todos os argumentos necessários estejam em cima da pilha em ordem decrescente. A referência obj
de instância (sempre necessária para ) deve ser enviada por callvirt
push antes de qualquer um dos argumentos visíveis pelo usuário. A assinatura (carregada no token de metadados) não precisa conter uma entrada na lista de parâmetros para esse ponteiro.
Observe que um método virtual também pode ser chamado usando a Call instrução .
MissingMethodException será gerado se um método não estático com o nome e a assinatura indicados não puder ser encontrado na classe associada obj
a ou em qualquer uma de suas classes base. Normalmente, isso é detectado quando as instruções da MSIL (Linguagem Intermediária da Microsoft) são convertidas em código nativo, em vez de em runtime.
NullReferenceException será gerado se obj for nulo.
SecurityException será gerado se a segurança do sistema não conceder ao chamador acesso ao método chamado. A marcar de segurança pode ocorrer quando o CIL é convertido em código nativo em vez de em tempo de execução.
Observação
Ao chamar métodos de System.Object em tipos de valor, considere usar o constrained
prefixo com a callvirt
instrução . Isso remove a necessidade de emitir IL diferente dependendo se o tipo de valor substitui ou não o método, evitando um possível problema de controle de versão. Considere usar o constrained
prefixo ao invocar métodos de interface em tipos de valor, já que o método de tipo de valor que implementa o método de interface pode ser alterado usando um MethodImpl
. Esses problemas são descritos mais detalhadamente no Constrained opcode.
A sobrecarga do método Emit a seguir pode usar o callvirt
opcode: