Partilhar via


OpCodes.Callvirt Campo

Definição

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 obja .

O comportamento de transição da pilha, em ordem sequencial, é:

  1. Uma referência obj de objeto é enviada por push para a pilha.

  2. Os argumentos de método são argN enviados arg1 por push para a pilha.

  3. Os argumentos arg1 de método por meio argN de e a referência obj de objeto são exibidos da pilha; a chamada de método é executada com esses argumentos e o controle é transferido para o método em obj referenciado pelo token de metadados do método. Quando concluído, um valor retornado é gerado pelo método chamador e enviado ao chamador.

  4. 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 callvirtpush 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:

Aplica-se a