Compartilhar via


Classe System.Reflection.Emit.DynamicMethod

Este artigo fornece comentários complementares à documentação de referência para esta API.

Você pode usar a DynamicMethod classe para gerar e executar um método em runtime, sem precisar gerar um assembly dinâmico e um tipo dinâmico para conter o método. O código executável criado pelo compilador just-in-time (JIT) é recuperado quando o DynamicMethod objeto é recuperado. Métodos dinâmicos são a maneira mais eficiente de gerar e executar pequenas quantidades de código.

Um método dinâmico pode ser hospedado anonimamente ou pode ser logicamente associado a um módulo ou a um tipo.

  • Se o método dinâmico estiver hospedado anonimamente, ele estará localizado em um assembly fornecido pelo sistema e, portanto, será isolado de outro código. Por padrão, ele não tem acesso a dados não públicos. Um método dinâmico hospedado anonimamente pode ter a capacidade restrita de ignorar as verificações de visibilidade do compilador JIT, se lhe tiver sido concedido ReflectionPermission com a bandeira ReflectionPermissionFlag.RestrictedMemberAccess. O nível de confiança do assembly cujos membros não públicos são acessados pelo método dinâmico deve ser igual a ou um subconjunto do nível de confiança da pilha de chamadas que emitiu o método dinâmico. Para obter mais informações sobre métodos dinâmicos hospedados anonimamente, consulte Passo a passo: emitindo código em cenários de confiança parcial.

  • Se o método dinâmico estiver associado a um módulo que você especificar, o método dinâmico será efetivamente global para esse módulo. Ele pode acessar todos os tipos no módulo e todos os membros internal (Friend no Visual Basic) dos tipos. Você pode associar um método dinâmico a qualquer módulo, independentemente de ter criado o módulo, desde que a pilha de chamadas que inclui seu código possa atender a uma demanda por ReflectionPermission com a sinalização RestrictedMemberAccess. Se o sinalizador ReflectionPermissionFlag.MemberAccess estiver incluído na concessão, o método dinâmico poderá ignorar as verificações de visibilidade do compilador JIT e acessar os dados privados de todos os tipos de dados declarados no módulo ou em qualquer outro módulo em qualquer conjunto.

    Observação

    Quando você especifica o módulo com o qual um método dinâmico está associado, esse módulo não deve estar no assembly fornecido pelo sistema que é usado para hospedagem anônima.

  • Se o método dinâmico estiver associado a um tipo que você especificar, ele terá acesso a todos os membros do tipo, independentemente do nível de acesso. Além disso, as verificações de visibilidade JIT podem ser ignoradas. Isso proporciona ao método dinâmico acesso aos dados privados de outros tipos declarados no mesmo módulo ou em qualquer outro módulo de qualquer assembly. Você pode associar um método dinâmico a qualquer tipo, mas seu código deve ser concedido a ReflectionPermission com os sinalizadores RestrictedMemberAccess e MemberAccess.

A tabela a seguir mostra quais tipos e membros estão acessíveis a um método dinâmico hospedado anonimamente, com e sem verificações de visibilidade JIT, dependendo se ReflectionPermission com o sinalizador RestrictedMemberAccess é concedido.

Verificações de visibilidade Sem RestrictedMemberAccess Com RestrictedMemberAccess
Sem pular as verificações de visibilidade JIT Membros públicos de tipos públicos em qualquer assembly. Membros públicos de tipos públicos em qualquer assembly.
Ignorando verificações de visibilidade JIT, com restrições Membros públicos de tipos públicos em qualquer assembly. Todos os membros de todos os tipos, somente em assemblies cujos níveis de confiança são iguais ou menores que o nível de confiança do assembly que gerou o método dinâmico.

A tabela a seguir mostra quais tipos e membros são acessíveis a um método dinâmico associado a um módulo ou a um tipo em um módulo.

Ignorar verificações de visibilidade JIT Associado ao módulo Associado ao tipo
Não Membros públicos e internos de tipos públicos, internos e privados no módulo.

Membros públicos de tipos públicos em qualquer assembly.
Todos os membros do tipo associado. Membros públicos e internos de todos os outros tipos no módulo.

Membros públicos de tipos públicos em qualquer assembly.
Sim Todos os membros de todos os tipos em qualquer assembly. Todos os membros de todos os tipos em qualquer assembly.

Um método dinâmico associado a um módulo tem as permissões desse módulo. Um método dinâmico associado a um tipo tem as permissões do módulo que contém esse tipo.

Métodos dinâmicos e seus parâmetros não precisam ser nomeados, mas você pode especificar nomes para ajudar na depuração. Não há suporte para atributos personalizados em métodos dinâmicos ou em seus parâmetros.

Embora os métodos dinâmicos sejam static métodos (Shared métodos no Visual Basic), as regras descontraídas para associação delegada permitem que um método dinâmico seja associado a um objeto, de modo que ele age como um método de instância quando chamado usando essa instância delegada. Um exemplo que demonstra isso é fornecido para a sobrecarga do método CreateDelegate(Type, Object).

Verificação

A lista a seguir resume as condições nas quais os métodos dinâmicos podem conter código não verificável. (Por exemplo, um método dinâmico será inverificável se sua InitLocals propriedade for definida como false.)

  • Um método dinâmico associado a um assembly crítico de segurança também é crítico à segurança e pode ignorar a verificação. Por exemplo, um assembly sem atributos de segurança executado como um aplicativo da área de trabalho é tratado como crítico de segurança pelo runtime. Se você associar um método dinâmico ao assembly, o método dinâmico poderá conter código não verificável.
  • Se um método dinâmico que contém código não verificável estiver associado a um assembly que tenha transparência de nível 1, o compilador JIT (just-in-time) injetará uma demanda de segurança. A demanda só será bem-sucedida se o método dinâmico for executado por um código totalmente confiável. Consulte Código transparente de segurança, nível 1.
  • Se um método dinâmico que contém código não verificável estiver associado a um assembly que tenha transparência de nível 2 (como mscorlib.dll), ele gerará uma exceção (injetada pelo compilador JIT) em vez de fazer uma demanda de segurança. Consulte Código transparente de segurança, nível 2.
  • Um método dinâmico hospedado anonimamente que contém código não verificável sempre gera uma exceção. Ele nunca pode ignorar a verificação, mesmo que ela seja criada e executada por um código totalmente confiável.

A exceção gerada para código não verificável varia dependendo da maneira como o método dinâmico é invocado. Se você invocar um método dinâmico usando um delegado retornado do CreateDelegate método, um VerificationException será gerado. Se você invocar o método dinâmico usando o método Invoke, um TargetInvocationException será gerado com um VerificationException interno.