Pobieranie informacji przechowywanych w atrybutach
Pobieranie atrybutu niestandardowego jest prostym procesem. Najpierw zadeklaruj wystąpienie atrybutu, który chcesz pobrać. Następnie użyj Attribute.GetCustomAttribute metody , aby zainicjować nowy atrybut do wartości atrybutu, który chcesz pobrać. Po zainicjowaniu nowego atrybutu można użyć jego właściwości, aby uzyskać wartości.
Ważne
W tym artykule opisano sposób pobierania atrybutów kodu załadowanego do kontekstu wykonywania. Aby pobrać atrybuty kodu załadowanego do kontekstu tylko odbicia, należy użyć CustomAttributeData klasy , jak pokazano w temacie How to: Load Assemblies into the Emocje ion-Only Context (Instrukcje: ładowanie zestawów do kontekstu tylko do Emocje iona).
W tej sekcji opisano następujące sposoby pobierania atrybutów:
Pobieranie wielu wystąpień atrybutu zastosowanego do tego samego zakresu
Pobieranie wielu wystąpień atrybutu zastosowanego do różnych zakresów
Pobieranie pojedynczego wystąpienia atrybutu
W poniższym przykładzie element DeveloperAttribute
(opisany w poprzedniej sekcji) jest stosowany do MainApp
klasy na poziomie klasy. Metoda GetAttribute
używa GetCustomAttribute
metody do pobierania wartości przechowywanych na DeveloperAttribute
poziomie klasy przed wyświetleniem ich w konsoli.
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
Wykonanie poprzedniego programu wyświetla następujący tekst:
The Name Attribute is: Joan Smith.
The Level Attribute is: 42.
The Reviewed Attribute is: True.
Jeśli atrybut nie zostanie znaleziony, GetCustomAttribute
metoda inicjuje MyAttribute
wartość null. Ten przykład sprawdza MyAttribute
takie wystąpienie i powiadamia użytkownika, jeśli atrybut nie zostanie znaleziony. Jeśli DeveloperAttribute
nie zostanie znaleziona w zakresie klasy, w konsoli zostanie wyświetlony następujący komunikat:
The attribute was not found.
W poprzednim przykładzie przyjęto założenie, że definicja atrybutu znajduje się w bieżącej przestrzeni nazw. Pamiętaj, aby zaimportować przestrzeń nazw, w której znajduje się definicja atrybutu, jeśli nie znajduje się w bieżącej przestrzeni nazw.
Pobieranie wielu wystąpień atrybutu zastosowanego do tego samego zakresu
W poprzednim przykładzie klasa do sprawdzenia i określonego atrybutu do znalezienia GetCustomAttribute są przekazywane do metody . Ten kod działa dobrze, jeśli na poziomie klasy jest stosowane tylko jedno wystąpienie atrybutu. Jeśli jednak na tym samym poziomie klasy zastosowano wiele wystąpień atrybutu, GetCustomAttribute
metoda nie pobiera wszystkich informacji. W przypadkach, gdy wiele wystąpień tego samego atrybutu jest stosowanych do tego samego zakresu, można użyć Attribute.GetCustomAttributes metody , aby umieścić wszystkie wystąpienia atrybutu w tablicy. Jeśli na przykład dwa wystąpienia DeveloperAttribute
klasy są stosowane na poziomie klasy tej samej klasy, GetAttribute
można zmodyfikować metodę w celu wyświetlenia informacji znalezionych w obu atrybutach. Pamiętaj, aby zastosować wiele atrybutów na tym samym poziomie. Atrybut musi być zdefiniowany z właściwością ustawioną AllowMultiple
AttributeUsageAttribute na true
w klasie.
W poniższym przykładzie kodu pokazano, jak za pomocą GetCustomAttributes
metody utworzyć tablicę odwołującą się do wszystkich wystąpień DeveloperAttribute
w dowolnej klasie. Następnie kod zwraca wartości wszystkich atrybutów do konsoli.
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
Jeśli nie znaleziono atrybutów, ten kod powiadamia użytkownika. W przeciwnym razie zostaną wyświetlone informacje zawarte w obu wystąpieniach DeveloperAttribute
programu .
Pobieranie wielu wystąpień atrybutu zastosowanego do różnych zakresów
Metody GetCustomAttributes i GetCustomAttribute nie wyszukują całej klasy i nie zwracają wszystkich wystąpień atrybutu w tej klasie. Zamiast tego wyszukują tylko jedną określoną metodę lub element członkowski naraz. Jeśli masz klasę o tym samym atrybucie zastosowanym do każdego elementu członkowskiego i chcesz pobrać wartości we wszystkich atrybutach zastosowanych do tych składowych, musisz podać każdą metodę lub składową pojedynczo do GetCustomAttributes
elementów i GetCustomAttribute
.
Poniższy przykład kodu przyjmuje klasę jako parametr i wyszukuje DeveloperAttribute
element (zdefiniowany wcześniej) na poziomie klasy i w każdej indywidualnej metodzie tej klasy:
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
Jeśli nie znaleziono żadnych wystąpień DeveloperAttribute
klasy na poziomie metody lub na poziomie klasy, GetAttribute
metoda powiadamia użytkownika, że nie znaleziono atrybutów i wyświetla nazwę metody lub klasy, która nie zawiera atrybutu. Jeśli zostanie znaleziony atrybut, konsola wyświetli Name
pola , Level
i Reviewed
.
Możesz użyć składowych Type klasy, aby uzyskać poszczególne metody i składowe w przekazanej klasie. W tym przykładzie najpierw wykonuje zapytanie dotyczące obiektu w Type
celu uzyskania informacji o atrybucie na poziomie klasy. Następnie używa Type.GetMethods metody do umieszczania wystąpień wszystkich metod w tablicy System.Reflection.MemberInfo obiektów w celu pobrania informacji o atrybutach na poziomie metody. Można również użyć Type.GetProperties metody , aby sprawdzić atrybuty na poziomie właściwości lub Type.GetConstructors sprawdzić atrybuty na poziomie konstruktora.