Compartilhar via


<Elemento Method> (.NET Native)

Aplica a política de reflexão de runtime a um construtor ou método.

Syntax

<Method Name="method_name"
        Signature="method_signature"
        Browse="policy_type"
        Dynamic="policy_type" />

Atributos e elementos

As seções a seguir descrevem atributos, elementos filho e elementos pai.

Atributos

Atributo Tipo de atributo Descrição
Name Geral Atributo obrigatório. Especifica o nome do método.
Signature Geral Atributo opcional. Especifica a assinatura do método. Se vários parâmetros estiverem presentes, eles são separados por vírgulas. Por exemplo, o elemento <Method> a seguir define a política para o método ToString(String, IFormatProvider).

<Type Name="System.DateTime"> <Method Name="ToString" Signature="System.String,System.IFormatProvider" Dynamic="Required" /> </Type>

Se o atributo estiver ausente, a diretiva de runtime se aplica a todas as sobrecargas do método.
Browse Reflexão Atributo opcional. Controla consultas para obter informações sobre o método ou para enumerá-lo, mas não permite qualquer invocação dinâmica no tempo de execução.
Dynamic Reflexão Atributo opcional. Controla o acesso do runtime a um construtor ou método para habilitar a programação dinâmica. Essa política garante que um membro pode ser invocado dinamicamente no tempo de execução.

Atributo de nome

Valor Descrição
method_name O nome do método. O tipo do método é definido pelo elemento pai< Type> ou <TypeInstantiation>.

Atributo de assinatura

Valor Descrição
method_signature Os tipos de parâmetros que formam a assinatura do método. Vários parâmetros são separados por vírgulas, por exemplo, "System.String,System.Int32,System.Int32)". Nomes de tipo de parâmetro devem ser totalmente qualificados.

Todos os outros atributos

Valor Descrição
policy_setting A configuração a ser aplicada a este tipo de política. Os valores possíveis são Auto, Excluded, Included e Required. Para obter mais informações, consulte Configurações da política da diretiva de runtime.

Elementos filho

Elemento Descrição
<Parâmetro> Aplica a política ao tipo do argumento passado para um método.
<GenericParameter> Aplica a política ao tipo de parâmetro de um tipo ou método genérico.
<ImpliesType> Aplica a política a um tipo, se esta política tiver sido aplicada ao método representado pelo elemento <Method> recipiente.
<TypeParameter> Aplica a política ao tipo representado por um argumento Type passado para um método.

Elementos pai

Elemento Descrição
<Type> Aplica a política de reflexão a um tipo e todos os seus membros.
<TypeInstantiation> Aplica a política de reflexão a um tipo genérico construído e todos os seus membros.

Comentários

Um elemento <Method> de um método genérico aplica sua política a todas as instanciações que não possuem sua própria política.

Você pode usar o atributo Signature para especificar uma política para uma sobrecarga de método específico. Caso contrário, se o atributo Signature estiver ausente, a diretiva de runtime se aplicará a todas as sobrecargas do método.

Não é possível definir a política de reflexão de runtime de um construtor usando o <Method> elemento. Em vez disso, use o Activate atributo do <elemento Assembly>, <Namespace>, <Type> ou <TypeInstantiation> .

Exemplo

O método Stringify no exemplo a seguir é um método de formatação para fins gerais que usa reflexão para converter um objeto em sua representação de cadeia de caracteres. Além de chamar o método ToString padrão do objeto, o método pode produzir uma cadeia de caracteres de resultados formatada passando um método ToString do objeto método em uma cadeia de caracteres, uma implementação de IFormatProvider ou ambos. Ele também pode chamar uma das sobrecargas de Convert.ToString que converte um número em sua representação octal, hexadecimal ou binária.

public class Stringify
{
   public static string ConvertToString(Object[] obj)
   {
      if (obj == null)
         throw new NullReferenceException("The obj parameter cannot be null.");

      if (obj.Length == 0) return String.Empty;

      if (obj[0].GetType() == typeof(String))
         return obj[0] as string;

      if (obj.Length == 1) return obj[0].ToString();

      if (obj.Length > 3)
         throw new ArgumentOutOfRangeException("The array can have from zero to three elements.");

      string retval = "";

      // Parameters indicate either a format specifier, numeric base, or format provider,
      // or a format specifier with an IFormatProvider.

      // A string as the first parameter indicates a format specifier.
      if (obj[1].GetType() == typeof(String)) {
         Type t = obj[0].GetType();
         if (obj.Length == 2)
         {
            MethodInfo m = t.GetRuntimeMethod("ToString", new Type[] { typeof(String) });
            retval = m.Invoke(obj[0], new object[] { obj[1] }).ToString();
         }
         else
         {
             MethodInfo m = t.GetRuntimeMethod("ToString", new Type[] { typeof(String), obj[2].GetType() });
             retval = m.Invoke(obj[0], new object[] { obj[1], obj[2] }).ToString();
         }
      }
      else if (obj[1] is IFormatProvider)
      {
          Type t = obj[0].GetType();
          MethodInfo m = t.GetRuntimeMethod("ToString", new Type[] { obj[1].GetType() } );
          retval = m.Invoke(obj[0], new object[] { obj[1] }).ToString();
      }
      // The second parameter is a base, so call Convert.ToString(number, int).
      else {
          Type t = typeof(Convert);
          MethodInfo m = t.GetRuntimeMethod("ToString", new Type[] { obj[0].GetType(), obj[1].GetType() } );
          retval = m.Invoke(null, obj).ToString();
      }
      return retval;
   }
}

O método Stringify pode ser chamado pelo código da seguinte maneira:

public class Stringify
{
   public static string ConvertToString(Object[] obj)
   {
      if (obj == null)
         throw new NullReferenceException("The obj parameter cannot be null.");

      if (obj.Length == 0) return String.Empty;

      if (obj[0].GetType() == typeof(String))
         return obj[0] as string;

      if (obj.Length == 1) return obj[0].ToString();

      if (obj.Length > 3)
         throw new ArgumentOutOfRangeException("The array can have from zero to three elements.");

      string retval = "";

      // Parameters indicate either a format specifier, numeric base, or format provider,
      // or a format specifier with an IFormatProvider.

      // A string as the first parameter indicates a format specifier.
      if (obj[1].GetType() == typeof(String)) {
         Type t = obj[0].GetType();
         if (obj.Length == 2)
         {
            MethodInfo m = t.GetRuntimeMethod("ToString", new Type[] { typeof(String) });
            retval = m.Invoke(obj[0], new object[] { obj[1] }).ToString();
         }
         else
         {
             MethodInfo m = t.GetRuntimeMethod("ToString", new Type[] { typeof(String), obj[2].GetType() });
             retval = m.Invoke(obj[0], new object[] { obj[1], obj[2] }).ToString();
         }
      }
      else if (obj[1] is IFormatProvider)
      {
          Type t = obj[0].GetType();
          MethodInfo m = t.GetRuntimeMethod("ToString", new Type[] { obj[1].GetType() } );
          retval = m.Invoke(obj[0], new object[] { obj[1] }).ToString();
      }
      // The second parameter is a base, so call Convert.ToString(number, int).
      else {
          Type t = typeof(Convert);
          MethodInfo m = t.GetRuntimeMethod("ToString", new Type[] { obj[0].GetType(), obj[1].GetType() } );
          retval = m.Invoke(null, obj).ToString();
      }
      return retval;
   }
}

No entanto, quando compilado com .NET Native, o exemplo pode acionar diversas exceções no tempo de execução, incluindo as exceções NullReferenceException e MissingRuntimeArtifactException. Isso ocorre porque o método Stringify destina-se principalmente a oferecer suporte à formatação dinâmica dos tipos primitivos na Biblioteca de Classes do .NET Framework. No entanto, seus metadados não são disponibilizados pelo arquivo de diretivas padrão. Mesmo quando seus metadados são disponibilizados, o exemplo aciona exceções MissingRuntimeArtifactException porque as devidas implementações ToString não foram incluídas no código nativo.

Todas essas exceções podem ser eliminadas usando o <elemento Type> para definir os tipos cujos metadados devem estar presentes e adicionando <Method> elementos para garantir que a implementação de sobrecargas de método que podem ser chamadas dinamicamente também esteja presente. Veja a seguir o arquivo default.rd.xml que elimina essas exceções e permite que o exemplo seja executado sem erros.

<Directives xmlns="http://schemas.microsoft.com/netfx/2013/01/metadata">
  <Application>
     <Assembly Name="*Application*" Dynamic="Required All" />

     <Type Name = "System.Convert" Browse="Required Public" Dynamic="Required Public" >
        <Method Name="ToString"    Dynamic ="Required" />
     </Type>
     <Type Name="System.Double" Browse="Required Public">
        <Method Name="ToString" Dynamic="Required" />
     </Type>
     <Type Name ="System.Int32" Browse="Required Public" >
        <Method Name="ToString" Dynamic="Required" />
     </Type>
     <Type Name ="System.Int64" Browse="Required Public" >
        <Method Name="ToString" Dynamic="Required" />
     </Type>
     <Namespace Name="System" >
        <Type Name="Byte" Browse="Required Public" >
           <Method Name="ToString" Dynamic="Required" />
        </Type>
        <Type Name="DateTime" Browse="Required Public" >
           <Method Name="ToString" Dynamic="Required" />
        </Type>
        <Type Name="Decimal" Browse="Required Public" >
           <Method Name="ToString" Dynamic="Required" />
        </Type>
        <Type Name="Guid" Browse ="Required Public" >
           <Method Name="ToString" Dynamic="Required" />
        </Type>
        <Type Name="Int16" Browse="Required Public" >
           <Method Name="ToString" Dynamic="Required" />
        </Type>
        <Type Name="SByte" Browse="Required Public" >
           <Method Name="ToString" Dynamic="Required" />
        </Type>
        <Type Name="Single" Browse="Required Public" >
          <Method Name="ToString" Dynamic="Required" />
        </Type>
        <Type Name="TimeSpan" Browse="Required Public" >
          <Method Name="ToString" Dynamic="Required" />
        </Type>
        <Type Name="UInt16" Browse="Required Public" >
           <Method Name="ToString" Dynamic="Required" />
        </Type>
        <Type Name="UInt32" Browse="Required Public" >
           <Method Name="ToString" Dynamic="Required" />
        </Type>
        <Type Name="UInt64" Browse="Required Public" >
           <Method Name="ToString" Dynamic="Required" />
        </Type>
     </Namespace>
  </Application>
</Directives>

Confira também