Recuperando informações armazenadas em atributos
Recuperar um atributo personalizado é um processo simples. Primeiro, declare uma instância do atributo que você deseja recuperar. Em seguida, use o método Attribute.GetCustomAttribute para inicializar o novo atributo para o valor do atributo que você deseja recuperar. Depois que o novo atributo for inicializado, você poderá usar suas propriedades para obter os valores.
Importante
Este artigo descreve como recuperar atributos para código carregado no contexto de execução. Para recuperar atributos do código carregado no contexto somente reflexão, use a classe CustomAttributeData, conforme mostrado em Como carregar assemblies no contexto somente reflexão.
Esta seção descreve as seguintes maneiras de recuperar atributos:
Recuperação de várias instâncias de um atributo aplicado ao mesmo escopo
Recuperando várias instâncias de um atributo aplicado a escopos diferentes
Recuperando uma única instância de um atributo
No exemplo a seguir, o DeveloperAttribute
(descrito na seção anterior) é aplicado à classe MainApp
no nível da classe. O método GetAttribute
usa GetCustomAttribute
para recuperar os valores armazenados em DeveloperAttribute
no nível da classe antes de exibi-los no console.
using namespace System;
using namespace System::Reflection;
using namespace CustomCodeAttributes;
[Developer("Joan Smith", "42", Reviewed = true)]
ref class MainApp
{
public:
static void Main()
{
// Call function to get and display the attribute.
GetAttribute(MainApp::typeid);
}
static void GetAttribute(Type^ t)
{
// Get instance of the attribute.
DeveloperAttribute^ MyAttribute =
(DeveloperAttribute^) Attribute::GetCustomAttribute(t, DeveloperAttribute::typeid);
if (MyAttribute == nullptr)
{
Console::WriteLine("The attribute was not found.");
}
else
{
// Get the Name value.
Console::WriteLine("The Name Attribute is: {0}." , MyAttribute->Name);
// Get the Level value.
Console::WriteLine("The Level Attribute is: {0}." , MyAttribute->Level);
// Get the Reviewed value.
Console::WriteLine("The Reviewed Attribute is: {0}." , MyAttribute->Reviewed);
}
}
};
using System;
using System.Reflection;
using CustomCodeAttributes;
[Developer("Joan Smith", "42", Reviewed = true)]
class MainApp
{
public static void Main()
{
// Call function to get and display the attribute.
GetAttribute(typeof(MainApp));
}
public static void GetAttribute(Type t)
{
// Get instance of the attribute.
DeveloperAttribute MyAttribute =
(DeveloperAttribute) Attribute.GetCustomAttribute(t, typeof (DeveloperAttribute));
if (MyAttribute == null)
{
Console.WriteLine("The attribute was not found.");
}
else
{
// Get the Name value.
Console.WriteLine("The Name Attribute is: {0}." , MyAttribute.Name);
// Get the Level value.
Console.WriteLine("The Level Attribute is: {0}." , MyAttribute.Level);
// Get the Reviewed value.
Console.WriteLine("The Reviewed Attribute is: {0}." , MyAttribute.Reviewed);
}
}
}
Imports System.Reflection
Imports CustomCodeAttributes
<Developer("Joan Smith", "42", Reviewed:=True)>
Class MainApp
Public Shared Sub Main()
' Call function to get and display the attribute.
GetAttribute(GetType(MainApp))
End Sub
Public Shared Sub GetAttribute(t As Type)
' Get instance of the attribute.
Dim MyAttribute As DeveloperAttribute =
CType(Attribute.GetCustomAttribute(t, GetType(DeveloperAttribute)), DeveloperAttribute)
If MyAttribute Is Nothing Then
Console.WriteLine("The attribute was not found.")
Else
' Get the Name value.
Console.WriteLine("The Name Attribute is: {0}.", MyAttribute.Name)
' Get the Level value.
Console.WriteLine("The Level Attribute is: {0}.", MyAttribute.Level)
' Get the Reviewed value.
Console.WriteLine("The Reviewed Attribute is: {0}.", MyAttribute.Reviewed)
End If
End Sub
End Class
A execução do programa anterior exibe o seguinte texto:
The Name Attribute is: Joan Smith.
The Level Attribute is: 42.
The Reviewed Attribute is: True.
Se o atributo não for encontrado, o método GetCustomAttribute
inicializará MyAttribute
para um valor nulo. Este exemplo verifica MyAttribute
para essa instância e notifica o usuário se o atributo não for encontrado. Se DeveloperAttribute
não for encontrado no escopo da classe, o console exibirá a seguinte mensagem:
The attribute was not found.
O exemplo anterior pressupõe que a definição de atributo está no namespace atual. Lembre-se de importar o namespace no qual a definição do atributo reside se não estiver no namespace atual.
Recuperando várias instâncias de um atributo aplicado ao mesmo escopo
No exemplo anterior, a classe a ser inspecionada e o atributo específico a ser encontrado são passados para o método GetCustomAttribute. Esse código funcionará bem se apenas uma instância de um atributo for aplicada no nível da classe. No entanto, se várias instâncias de um atributo forem aplicadas no mesmo nível de classe, o método GetCustomAttribute
não recuperará todas as informações. Nos casos em que várias instâncias do mesmo atributo são aplicadas ao mesmo escopo, você pode usar Attribute.GetCustomAttributes método para colocar todas as instâncias de um atributo em uma matriz. Por exemplo, se duas instâncias de DeveloperAttribute
forem aplicadas no nível de classe da mesma classe, o método GetAttribute
poderá ser modificado para exibir as informações encontradas em ambos os atributos. Lembre-se de aplicar vários atributos no mesmo nível. O atributo deve ser definido com a propriedade AllowMultiple
definida como true
na classe AttributeUsageAttribute.
O exemplo de código a seguir mostra como usar o método GetCustomAttributes
para criar uma matriz que referencia todas as instâncias de DeveloperAttribute
em qualquer classe específica. Em seguida, o código gera os valores de todos os atributos para o console.
public:
static void GetAttribute(Type^ t)
{
array<DeveloperAttribute^>^ MyAttributes =
(array<DeveloperAttribute^>^) Attribute::GetCustomAttributes(t, DeveloperAttribute::typeid);
if (MyAttributes->Length == 0)
{
Console::WriteLine("The attribute was not found.");
}
else
{
for (int i = 0 ; i < MyAttributes->Length; i++)
{
// Get the Name value.
Console::WriteLine("The Name Attribute is: {0}." , MyAttributes[i]->Name);
// Get the Level value.
Console::WriteLine("The Level Attribute is: {0}." , MyAttributes[i]->Level);
// Get the Reviewed value.
Console::WriteLine("The Reviewed Attribute is: {0}.", MyAttributes[i]->Reviewed);
}
}
}
public static void GetAttribute(Type t)
{
DeveloperAttribute[] MyAttributes =
(DeveloperAttribute[]) Attribute.GetCustomAttributes(t, typeof (DeveloperAttribute));
if (MyAttributes.Length == 0)
{
Console.WriteLine("The attribute was not found.");
}
else
{
for (int i = 0 ; i < MyAttributes.Length ; i++)
{
// Get the Name value.
Console.WriteLine("The Name Attribute is: {0}." , MyAttributes[i].Name);
// Get the Level value.
Console.WriteLine("The Level Attribute is: {0}." , MyAttributes[i].Level);
// Get the Reviewed value.
Console.WriteLine("The Reviewed Attribute is: {0}.", MyAttributes[i].Reviewed);
}
}
}
Public Shared Sub GetAttribute(t As Type)
Dim MyAttributes() As DeveloperAttribute =
CType(Attribute.GetCustomAttributes(t, GetType(DeveloperAttribute)), DeveloperAttribute())
If MyAttributes.Length = 0 Then
Console.WriteLine("The attribute was not found.")
Else
For i As Integer = 0 To MyAttributes.Length - 1
' Get the Name value.
Console.WriteLine("The Name Attribute is: {0}.", MyAttributes(i).Name)
' Get the Level value.
Console.WriteLine("The Level Attribute is: {0}.", MyAttributes(i).Level)
' Get the Reviewed value.
Console.WriteLine("The Reviewed Attribute is: {0}.", MyAttributes(i).Reviewed)
Next i
End If
End Sub
Se nenhum atributo for encontrado, esse código alertará o usuário. Caso contrário, as informações contidas nas duas instâncias de DeveloperAttribute
serão exibidas.
Recuperando várias instâncias de um atributo aplicado a escopos diferentes
Os métodos GetCustomAttributes e GetCustomAttribute não pesquisam uma classe inteira e retornam todas as instâncias de um atributo nessa classe. Em vez disso, eles pesquisam apenas um método ou membro especificado por vez. Se você tiver uma classe com o mesmo atributo aplicado a cada membro e quiser recuperar os valores em todos os atributos aplicados a esses membros, deverá fornecer todos os métodos ou membros individualmente para GetCustomAttributes
e GetCustomAttribute
.
O exemplo de código a seguir usa uma classe como parâmetro e pesquisa o DeveloperAttribute
(definido anteriormente) no nível da classe e em cada método individual dessa classe:
public:
static void GetAttribute(Type^ t)
{
DeveloperAttribute^ att;
// Get the class-level attributes.
// Put the instance of the attribute on the class level in the att object.
att = (DeveloperAttribute^) Attribute::GetCustomAttribute (t, DeveloperAttribute::typeid);
if (att == nullptr)
{
Console::WriteLine("No attribute in class {0}.\n", t->ToString());
}
else
{
Console::WriteLine("The Name Attribute on the class level is: {0}.", att->Name);
Console::WriteLine("The Level Attribute on the class level is: {0}.", att->Level);
Console::WriteLine("The Reviewed Attribute on the class level is: {0}.\n", att->Reviewed);
}
// Get the method-level attributes.
// Get all methods in this class, and put them
// in an array of System.Reflection.MemberInfo objects.
array<MemberInfo^>^ MyMemberInfo = t->GetMethods();
// Loop through all methods in this class that are in the
// MyMemberInfo array.
for (int i = 0; i < MyMemberInfo->Length; i++)
{
att = (DeveloperAttribute^) Attribute::GetCustomAttribute(MyMemberInfo[i], DeveloperAttribute::typeid);
if (att == nullptr)
{
Console::WriteLine("No attribute in member function {0}.\n" , MyMemberInfo[i]->ToString());
}
else
{
Console::WriteLine("The Name Attribute for the {0} member is: {1}.",
MyMemberInfo[i]->ToString(), att->Name);
Console::WriteLine("The Level Attribute for the {0} member is: {1}.",
MyMemberInfo[i]->ToString(), att->Level);
Console::WriteLine("The Reviewed Attribute for the {0} member is: {1}.\n",
MyMemberInfo[i]->ToString(), att->Reviewed);
}
}
}
public static void GetAttribute(Type t)
{
DeveloperAttribute att;
// Get the class-level attributes.
// Put the instance of the attribute on the class level in the att object.
att = (DeveloperAttribute) Attribute.GetCustomAttribute (t, typeof (DeveloperAttribute));
if (att == null)
{
Console.WriteLine("No attribute in class {0}.\n", t.ToString());
}
else
{
Console.WriteLine("The Name Attribute on the class level is: {0}.", att.Name);
Console.WriteLine("The Level Attribute on the class level is: {0}.", att.Level);
Console.WriteLine("The Reviewed Attribute on the class level is: {0}.\n", att.Reviewed);
}
// Get the method-level attributes.
// Get all methods in this class, and put them
// in an array of System.Reflection.MemberInfo objects.
MemberInfo[] MyMemberInfo = t.GetMethods();
// Loop through all methods in this class that are in the
// MyMemberInfo array.
for (int i = 0; i < MyMemberInfo.Length; i++)
{
att = (DeveloperAttribute) Attribute.GetCustomAttribute(MyMemberInfo[i], typeof (DeveloperAttribute));
if (att == null)
{
Console.WriteLine("No attribute in member function {0}.\n" , MyMemberInfo[i].ToString());
}
else
{
Console.WriteLine("The Name Attribute for the {0} member is: {1}.",
MyMemberInfo[i].ToString(), att.Name);
Console.WriteLine("The Level Attribute for the {0} member is: {1}.",
MyMemberInfo[i].ToString(), att.Level);
Console.WriteLine("The Reviewed Attribute for the {0} member is: {1}.\n",
MyMemberInfo[i].ToString(), att.Reviewed);
}
}
}
Public Shared Sub GetAttribute(t As Type)
Dim att As DeveloperAttribute
' Get the class-level attributes.
' Put the instance of the attribute on the class level in the att object.
att = CType(Attribute.GetCustomAttribute(t, GetType(DeveloperAttribute)), DeveloperAttribute)
If att Is Nothing
Console.WriteLine("No attribute in class {0}.\n", t.ToString())
Else
Console.WriteLine("The Name Attribute on the class level is: {0}.", att.Name)
Console.WriteLine("The Level Attribute on the class level is: {0}.", att.Level)
Console.WriteLine("The Reviewed Attribute on the class level is: {0}.\n", att.Reviewed)
End If
' Get the method-level attributes.
' Get all methods in this class, and put them
' in an array of System.Reflection.MemberInfo objects.
Dim MyMemberInfo() As MemberInfo = t.GetMethods()
' Loop through all methods in this class that are in the
' MyMemberInfo array.
For i As Integer = 0 To MyMemberInfo.Length - 1
att = CType(Attribute.GetCustomAttribute(MyMemberInfo(i), _
GetType(DeveloperAttribute)), DeveloperAttribute)
If att Is Nothing Then
Console.WriteLine("No attribute in member function {0}.\n", MyMemberInfo(i).ToString())
Else
Console.WriteLine("The Name Attribute for the {0} member is: {1}.",
MyMemberInfo(i).ToString(), att.Name)
Console.WriteLine("The Level Attribute for the {0} member is: {1}.",
MyMemberInfo(i).ToString(), att.Level)
Console.WriteLine("The Reviewed Attribute for the {0} member is: {1}.\n",
MyMemberInfo(i).ToString(), att.Reviewed)
End If
Next
End Sub
Se nenhuma instância do DeveloperAttribute
for encontrada no nível do método ou no nível da classe, o método GetAttribute
notificará o usuário de que nenhum atributo foi encontrado e exibirá o nome do método ou classe que não contém o atributo. Se um atributo for encontrado, o console exibirá os campos Name
, Level
e Reviewed
.
Você pode usar os membros da classe Type para obter os métodos e membros individuais na classe passada. Este exemplo primeiro consulta o objeto Type
para obter informações de atributo para o nível de classe. Em seguida, ele usa Type.GetMethods para colocar instâncias de todos os métodos em uma matriz de objetos System.Reflection.MemberInfo para recuperar informações de atributo para o nível do método. Você também pode usar o método Type.GetProperties para verificar se há atributos no nível da propriedade ou Type.GetConstructors para verificar se há atributos no nível do construtor.
Recuperando atributos de membros de classe
Além de recuperar atributos no nível da classe, os atributos também podem ser aplicados a membros individuais, como métodos, propriedades e campos. Os métodos GetCustomAttribute
e GetCustomAttributes
podem ser usados para recuperar esses atributos.
Exemplo
O exemplo a seguir demonstra como recuperar um atributo aplicado a um método:
using System;
using System.Reflection;
[AttributeUsage(AttributeTargets.Method)]
public class MyAttribute : Attribute
{
public string Description { get; }
public MyAttribute(string description) { Description = description; }
}
public class MyClass
{
[MyAttribute("This is a sample method.")]
public void MyMethod() { }
}
class AttributeRetrieval
{
public static void Main()
{
// Create an instance of MyClass
MyClass myClass = new MyClass();
// Retrieve the method information for MyMethod
MethodInfo methodInfo = typeof(MyClass).GetMethod("MyMethod");
MyAttribute attribute = (MyAttribute)Attribute.GetCustomAttribute(methodInfo, typeof(MyAttribute));
if (attribute != null)
{
// Print the description of the method attribute
Console.WriteLine("Method Attribute: {0}", attribute.Description);
}
else
{
Console.WriteLine("Attribute not found.");
}
}
}