<Элемент 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>