<Elemento> Method (.NET Native)

Applica i criteri di reflection di runtime a un costruttore o a un metodo.

Sintassi

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

Attributi ed elementi

Nelle sezioni seguenti vengono descritti gli attributi, gli elementi figlio e gli elementi padre.

Attributi

Attributo Tipo di attributo Descrizione
Name Generali Attributo obbligatorio. Specifica il nome del metodo.
Signature Generali Attributo facoltativo. Specifica la firma del metodo. Se esistono più parametri, sono separati da virgole. Ad esempio, l'elemento <Method> seguente definire i criteri del metodo ToString(String, IFormatProvider).

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

Se l'attributo è assente, la direttiva di runtime si applica a tutti gli overload del metodo.
Browse Reflection Attributo facoltativo. Controlla l'esecuzione di query per informazioni sul metodo o la sua enumerazione, ma non abilita alcuna chiamata dinamica in fase di esecuzione.
Dynamic Reflection Attributo facoltativo. Controlla l'accesso del runtime a un costruttore o al metodo per attivare la programmazione dinamica. Questo criterio assicura che un membro possa essere richiamato in modo dinamico in fase di esecuzione.

Name (attributo)

Valore Descrizione
method_name Nome del metodo. Il tipo di metodo viene definito dall'elemento <Type> o <TypeInstantiation> padre.

Attributo Signature

Valore Descrizione
method_signature Tipi di parametri che costituiscono la firma del metodo. Più parametri sono separati da virgole, ad esempio "System.String,System.Int32,System.Int32)". I nomi del tipo di parametro devono essere completi.

Tutti gli altri attributi

Valore Descrizione
policy_setting L'impostazione da applicare a questo tipo di criteri. I valori consentiti sono Auto, Excluded, Included e Required. Per altre informazioni, vedere Runtime Directive Policy Settings (Impostazioni dei criteri delle direttive di runtime).

Elementi figlio

Elemento Descrizione
<Parametro> Applica i criteri al tipo di argomento passato a un metodo.
<GenericParameter> Applica i criteri al tipo di parametro di un tipo o di un metodo generico.
<ImpliesType> Applica criteri a un tipo, se tale criterio è stato applicato al metodo rappresentato dall'oggetto contenente l'elemento <Method>.
<TypeParameter> Applica i criteri al tipo rappresentato da un argomento Type passato a un metodo.

Elementi padre

Elemento Descrizione
<Tipo> Applica i criteri di reflection a un tipo e a tutti i membri.
<TypeInstantiation> Applica i criteri di reflection a un tipo generico costruito e a tutti i membri.

Osservazioni:

Un elemento <Method> di un metodo generico applica i relativi criteri a tutte le istanze che non dispongono di propri criteri.

È possibile usare l'attributo Signature per specificare criteri per un overload del metodo specifico. In caso contrario, se l'attributo Signature è assente, la direttiva di runtime si applica a tutti gli overload del metodo.

Non è possibile definire i criteri di reflection di runtime per un costruttore con l'elemento <Method>. Usare invece Activate l'attributo dell'elemento <Assembly>, <Namespace>, <Type>, o <TypeInstantiation>.

Esempio

Il metodo Stringify nell'esempio seguente è un metodo di formattazione generico che usa la reflection per convertire un oggetto nella relativa rappresentazione di stringa. Oltre a chiamare il metodo ToString predefinito dell'oggetto, il metodo può produrre una stringa di risultato formattata passando il metodo ToString di un oggetto a una stringa di formato, un'implementazione di IFormatProvider o entrambi. Il metodo può anche chiamare uno degli overload Convert.ToString che converte un numero nella relativa rappresentazione binaria, ottale o esadecimale.

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;
   }
}

Il metodo Stringify può essere chiamato da codice simile al seguente:

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;
   }
}

Tuttavia, quando viene compilato con .NET Native, l'esempio può generare una serie di eccezioni in fase di esecuzione, incluse le eccezioni NullReferenceException e MissingRuntimeArtifactException. Ciò si verifica perché il metodo Stringify è destinato principalmente a supportare la formattazione dinamica dei tipi primitivi nella libreria di classi .NET Framework. Tuttavia, i metadati non vengono resi disponibili dal file di direttive predefinito. Anche quando i metadati vengono resi disponibili, tuttavia, l'esempio genererà le eccezioni MissingRuntimeArtifactException perché le implementazioni ToString appropriate non sono state incluse nel codice nativo.

Queste eccezioni possono essere eliminate usando l'elemento <Type> per definire i tipi i cui metadati devono essere presenti e aggiungendo <Method> elementi per garantire che l'implementazione degli overload di metodi che possono essere richiamati dinamicamente sia presente. Di seguito è riportato il file default.rd.xml che elimina queste eccezioni e consente l'esecuzione dell'esempio senza errori.

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

Vedi anche