Načítání informací uložených v atributech
Načtení vlastního atributu je jednoduchý proces. Nejprve deklarujte instanci atributu, který chcete načíst. Potom použijte Attribute.GetCustomAttribute metodu k inicializaci nového atributu na hodnotu atributu, který chcete načíst. Po inicializaci nového atributu můžete k získání hodnot použít jeho vlastnosti.
Důležitý
Tento článek popisuje, jak načíst atributy pro kód načtený do kontextu spuštění. Chcete-li načíst atributy kódu načteného do pouze-reflexního kontextu, je nutné použít třídu CustomAttributeData, jak je znázorněno v Postup: Načtení sestavení do kontextu Reflection-Only.
Tato část popisuje následující způsoby načtení atributů:
Načtení jedné instance atributu
V následujícím příkladu se DeveloperAttribute
(popsané v předchozí části) použije na třídu MainApp
na úrovni třídy. Metoda GetAttribute
používá GetCustomAttribute
k načtení hodnot uložených v DeveloperAttribute
na úrovni třídy před jejich zobrazením do konzoly.
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
Spuštění předchozího programu zobrazí následující text:
The Name Attribute is: Joan Smith.
The Level Attribute is: 42.
The Reviewed Attribute is: True.
Pokud se atribut nenajde, metoda GetCustomAttribute
inicializuje MyAttribute
na hodnotu null. Tento příklad zkontroluje MyAttribute
pro takovou instanci a upozorní uživatele, pokud atribut nebyl nalezen. Pokud DeveloperAttribute
není nalezen v oboru třídy, konzola zobrazí následující zprávu:
The attribute was not found.
Předchozí příklad předpokládá, že definice atributu je v aktuálním oboru názvů. Nezapomeňte importovat obor názvů, ve kterém se nachází definice atributu, pokud není v aktuálním oboru názvů.
Načtení více instancí atributu vztahujícího se na tentýž obor
V předchozím příkladu se třída, která má zkontrolovat, a konkrétní atribut, který se má najít, předá metodě GetCustomAttribute. Tento kód funguje dobře, pokud se na úrovni třídy použije pouze jedna instance atributu. Pokud je však na stejné úrovni třídy použito více instancí atributu, metoda GetCustomAttribute
nenačte všechny informace. V případech, kdy se na stejný obor použije více instancí stejného atributu, můžete použít metodu Attribute.GetCustomAttributes k umístění všech instancí atributu do pole. Pokud jsou například na úrovni třídy stejné třídy použity dvě instance DeveloperAttribute
, lze metodu GetAttribute
upravit tak, aby zobrazovala informace nalezené v obou atributech. Nezapomeňte aplikovat více atributů na stejné úrovni. Atribut musí být definován s vlastností AllowMultiple
nastavenou na true
ve třídě AttributeUsageAttribute.
Následující příklad kódu ukazuje, jak použít GetCustomAttributes
metoda k vytvoření pole, které odkazuje na všechny instance DeveloperAttribute
v libovolné dané třídě. Kód pak vypíše hodnoty všech atributů do konzoly.
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
Pokud nejsou nalezeny žádné atributy, tento kód upozorní uživatele. V opačném případě se zobrazí informace, které jsou obsažené v obou instancích DeveloperAttribute
.
Načtení více instancí atributu použitého na různé obory
Metody GetCustomAttributes a GetCustomAttribute nehledají celou třídu, ani nevracejí všechny instance atributu v této třídě. Místo toho prohledávají současně pouze jednu zadanou metodu nebo člena. Pokud máte třídu se stejným atributem použitým pro každý člen a chcete načíst hodnoty ve všech atributech použitých u těchto členů, je nutné zadat každou metodu nebo člen jednotlivě pro GetCustomAttributes
a GetCustomAttribute
.
Následující příklad kódu přebírá třídu jako parametr a hledá DeveloperAttribute
(definované dříve) na úrovni třídy a pro každou jednotlivou metodu této třídy:
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
Pokud nejsou nalezeny žádné instance DeveloperAttribute
na úrovni metody nebo na úrovni třídy, GetAttribute
metoda upozorní uživatele, že nebyly nalezeny žádné atributy, a zobrazí název metody nebo třídy, která neobsahuje atribut. Pokud se najde atribut, konzola zobrazí pole Name
, Level
a Reviewed
.
Členy třídy Type můžete použít k získání jednotlivých metod a členů v předané třídě. Tento příklad nejprve dotazuje objekt Type
pro získání informací o atributu pro úroveň třídy. Dále používá Type.GetMethods k umístění instancí všech metod do pole System.Reflection.MemberInfo objektů k načtení informací o atributech pro úroveň metody. Můžete také použít metodu Type.GetProperties ke kontrole atributů na úrovni vlastnosti nebo Type.GetConstructors ke kontrole atributů na úrovni konstruktoru.
Načítání atributů ze členů třídy
Kromě načítání atributů na úrovni třídy lze atributy použít také u jednotlivých členů, jako jsou metody, vlastnosti a pole. K načtení těchto atributů lze použít metody GetCustomAttribute
a GetCustomAttributes
.
Příklad
Následující příklad ukazuje, jak načíst atribut použitý na metodu:
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.");
}
}
}