Поделиться через


<Элемент Method> (.NET Native)

Применяет политику отражения среды выполнения к конструктору или методу.

Синтаксис

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

Атрибуты и элементы

В следующих разделах описаны атрибуты, дочерние и родительские элементы.

Атрибуты

Атрибут Тип атрибута Description
Name Общие Обязательный атрибут элемента . Задает имя метода.
Signature Общие Необязательный атрибут элемента . Задает подпись метода. При наличии нескольких параметров, они разделяются запятыми. Например, следующий элемент <Method> определяет политику для метода ToString(String, IFormatProvider).

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

Если атрибут отсутствует, директива среды выполнения применяется для всех перегруженных версий метода.
Browse Отражение Необязательный атрибут элемента . Определяет запрос для получения сведений о методе или перечисляет методы, но не включает динамический вызов во время выполнения.
Dynamic Отражение Необязательный атрибут элемента . Управляет доступом среды выполнения к конструктору или методу для включения динамического программирования. Эта политика гарантирует, что член может быть вызван динамически во время выполнения.

Name - атрибут

значение Описание
method_name Имя метода. Тип метода определяется родительским элементом Type или< TypeInstantiation>>.<

Сигнатура атрибута

значение Описание
method_signature Типы параметров, которые образуют сигнатуру метода. Несколько параметров разделяются запятыми, например, "System.String,System.Int32,System.Int32)". Имена параметров типа должно быть полными.

Все остальные атрибуты

значение Описание
policy_setting Параметр, применяемый для этого типа политики. Допустимые значения: Auto, Excluded, Included и Required. Дополнительные сведения см. в разделе Параметры политики директив среды выполнения.

Дочерние элементы

Элемент Description
<Параметр> Применяет политику к типу аргумента, переданного методу.
<GenericParameter> Применяет политику к параметру типа универсального типа или метода.
<ImpliesType> Применяет политику к типу, если политика была применена для метода, представленного содержащим элементом <Method>.
<TypeParameter> Применяет политику к типу, представленному аргументом Type, переданным методу.

Родительские элементы

Элемент Описание
<Тип> Применяет политику отражения к типу и всем его членам.
<TypeInstantiation> Применяет политику отражения к сконструированному универсальному типу и всем его членам.

Замечания

Элемент <Method> универсального метода применяет свою политику для всех экземпляров, которые не имеют собственной политики.

Можно использовать атрибут Signature, чтобы задать политику для перегрузки определенного метода. В противном случае, если атрибут Signature отсутствует, директива среды выполнения применяется для всех перегруженных версий метода.

Нельзя определить политику отражения среды выполнения для конструктора, используя элемент <Method>. Вместо этого используйте Activate атрибут элемента Assembly>,< Namespace>,< Type> или< TypeInstantiation>.<

Пример

Метод Stringify в следующем примере – это универсальный метод форматирования, который использует отражение для преобразования объекта в строковое представление. Помимо вызова метода ToString по умолчанию объекта , метод может создать отформатированную результирующую строку путем передачи методу ToString объекта строки формата, реализации IFormatProvider, или и то и другое. Он также может вызвать одну из перегрузок Convert.ToString, которая преобразует число в двоичное, шестнадцатеричное или восьмеричное представление.

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

Метод Stringify может быть вызван таким кодом, как указан ниже:

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

Однако при компиляции с помощью .NET Native пример может вызывать ряд исключений во время выполнения, включая NullReferenceException и исключения MissingRuntimeArtifactException, это происходит, так как Stringify метод предназначен в основном для поддержки динамического форматирования примитивных типов в библиотеке классов платформа .NET Framework. Однако их метаданные не становятся доступными в файле директив по умолчанию. Даже в том случае, если метаданные доступны, в примере возникают исключения MissingRuntimeArtifactException, поскольку соответствующие реализации ToString не были включены в машинный код.

Все эти исключения можно устранить с помощью <элемента Type> для определения типов, метаданные которых должны присутствовать, и путем добавления <Method> элементов, чтобы гарантировать, что реализация перегрузки методов, которые можно вызывать динамически, также присутствует. Ниже приведен файл default.rd.xml, который устраняет эти исключения и позволяет выполнить пример без ошибок.

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

См. также