<Elemento de método> (.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. |
<Parâmetro genérico> | 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. |
<Parâmetro de tipo> | Aplica a política ao tipo representado por um argumento Type passado para um método. |
Elementos pai
Elemento | Descrição |
---|---|
<Tipo> | 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 o .NET Native, o exemplo pode gerar várias exceções em runtime, incluindo NullReferenceException exceções e MissingRuntimeArtifactException , Isso ocorre porque o Stringify
método se destina principalmente a dar 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>