Abrufen von Informationen aus Attributen
Aktualisiert: November 2007
Das Abrufen eines benutzerdefinierten Attributs ist ein unkomplizierter Vorgang. Deklarieren Sie zunächst eine Instanz des Attributs, das abgerufen werden soll. Initialisieren Sie dann das neue Attribut mithilfe der Attribute.GetCustomAttribute-Methode mit dem Wert des abzurufenden Attributs. Nach der Initialisierung des neuen Attributs können Sie die Werte dann einfach über die Eigenschaften abrufen.
Wichtiger Hinweis: |
---|
In diesem Thema wird das Abrufen von Attributen für Code beschrieben, der in den Ausführungskontext geladen wurde. Um Attribute für Code abzurufen, der in den reflektionsbezogenen Kontext geladen wurde, verwenden Sie die CustomAttributeData-Klasse, wie unter Gewusst wie: Laden von Assemblys in den reflektionsbezogenen Kontext beschrieben. |
In diesem Abschnitt werden die folgenden Möglichkeiten zum Abrufen von Attributen beschrieben:
Abrufen einer einzigen Instanz eines Attributs
Abrufen mehrerer, auf denselben Gültigkeitsbereich angewendeter Instanzen eines Attributs
Abrufen mehrerer, auf verschiedene Gültigkeitsbereiche angewendeter Instanzen eines Attributs
Abrufen einer einzigen Instanz eines Attributs
Im folgenden Beispiel wird DeveloperAttribute, das im vorherigen Abschnitt beschrieben wurde, auf Klassenebene auf die MainApp-Klasse angewendet. Die GetAttribute-Methode verwendet GetCustomAttribute, um die in DeveloperAttribute auf Klassenebene gespeicherten Werte abzurufen, bevor sie auf der Konsole angezeigt werden.
using System;
[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(null == MyAttribute)
{
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
<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
Das Programm zeigt bei der Ausführung den folgenden Text an.
The Name Attribute is: Joan Smith.
The Level Attribute is: 42.
The Reviewed Attribute is: True.
Wenn das Attribut nicht gefunden wird, initialisiert die GetCustomAttribute-Methode MyAttribute mit einem NULL-Wert. In diesem Beispiel wird MyAttribute auf eine solche Instanz überprüft. Wenn kein Attribut gefunden wird, wird der Benutzer benachrichtigt. Wenn DeveloperAttribute im Gültigkeitsbereich der Klasse nicht gefunden werden kann, wird die folgende Meldung in der Konsole angezeigt.
The attribute was not found.
In diesem Beispiel wird vorausgesetzt, dass sich die Attributdefinition im aktuellen Namespace befindet. Daher müssen Sie den Namespace, in dem sich die Attributdefinition befindet, unbedingt importieren, sofern es sich nicht um den aktuellen Namespace handelt.
Abrufen mehrerer, auf denselben Gültigkeitsbereich angewendeter Instanzen eines Attributs
Im vorherigen Beispiel wurden die zu prüfende Klasse und das angegebene Attribut, das gesucht werden soll, an GetCustomAttribute übergeben. Dieser Code funktioniert dann problemlos, wenn nur eine Instanz eines Attributs auf Klassenebene angewendet wird. Wenn jedoch mehrere Instanzen eines Attributs auf derselben Klassenebene angewendet werden, ruft die GetCustomAttribute-Methode nicht alle Informationen ab. Wenn mehrere Instanzen des gleichen Attributs in demselben Gültigkeitsbereich angewendet werden, können Sie mit Attribute.GetCustomAttributes alle Instanzen eines Attributs in einem Array platzieren. Wenn z. B. zwei Instanzen von DeveloperAttribute auf Klassenebene derselben Klasse angewendet werden, können Sie die GetAttribute-Methode dahingehend ändern, dass sie die in beiden Attributen gefundenen Informationen anzeigt. Wenn Sie mehrere Attribute auf derselben Ebene anwenden möchten, müssen Sie die AllowMultiple-Eigenschaft im AttributeUsageAttribute auf true festlegen.
Das folgende Codebeispiel veranschaulicht, wie Sie mit der GetCustomAttributes-Methode ein Array erstellen, das auf sämtliche Instanzen von DeveloperAttribute in allen angegebenen Klassen verweist. Die Werte aller Attribute werden anschließend in der Konsole angezeigt.
public static void GetAttribute(Type t)
{
DeveloperAttribute[] MyAttribute =
(DeveloperAttribute[]) Attribute.GetCustomAttributes(t, typeof (DeveloperAttribute));
if(null == MyAttribute)
{
Console.WriteLine("The attribute was not found.");
}
else
{
for(int i = 0 ; i < MyAttribute.Length ; i++)
{
//Get the Name value.
Console.WriteLine("The Name Attribute is: {0}." , MyAttribute[i].Name);
//Get the Level value.
Console.WriteLine("The Level Attribute is: {0}." , MyAttribute[i].Level);
//Get the Reviewed value.
Console.WriteLine("The Reviewed Attribute is: {0}.", MyAttribute[i].Reviewed);
}
}
}
Public Shared Sub GetAttribute(t As Type)
Dim MyAttribute As DeveloperAttribute() = _
CType(Attribute.GetCustomAttributes(t, GetType(DeveloperAttribute)), DeveloperAttribute())
If MyAttribute Is Nothing Then
Console.WriteLine("The attribute was not found.")
Else
Dim i As Integer
For i = 0 To MyAttribute.Length - 1
'Get the Name value.
Console.WriteLine("The Name Attribute is: {0}.", MyAttribute(i).Name)
'Get the Level value.
Console.WriteLine("The Level Attribute is: {0}.", MyAttribute(i).Level)
'Get the Reviewed value.
Console.WriteLine("The Reviewed Attribute is: {0}.", MyAttribute(i).Reviewed)
Next i
End If
End Sub
Wenn keine Attribute gefunden werden, gibt der Code eine Warnung an den Benutzer aus. Andernfalls werden die in beiden Instanzen von DeveloperAttribute enthaltenen Informationen angezeigt.
Abrufen mehrerer, auf verschiedene Gültigkeitsbereiche angewendeter Instanzen eines Attributs
Die GetCustomAttributes-Methode und die GetCustomAttribute-Methode suchen nicht in der gesamten Klasse und geben nicht alle Instanzen eines Attributs in der Klasse zurück. Sie suchen jeweils nur in einer angegebenen Methode oder Eigenschaft. Angenommen, Sie verfügen über eine Klasse, in der auf alle Member dasselbe Attribut angewendet wurde. Um die Werte aller Attribute, die auf diese Member angewendet wurden, abzurufen, müssen Sie alle Methoden bzw. Member in GetCustomAttributes und GetCustomAttribute jeweils einzeln angeben.
Im folgenden Codebeispiel wird eine Klasse als Parameter verwendet und auf Klassenebene und in jeder einzelnen Methode der Klasse nach dem zuvor definierten DeveloperAttribute gesucht.
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(null == att)
{
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(null == att)
{
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 Then
Console.WriteLine("No attribute in class {0}.", t.ToString())
Console.WriteLine()
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}.", att.Reviewed)
Console.WriteLine()
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.
Dim i As Integer
For i = 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}.", MyMemberInfo(i).ToString())
Console.WriteLine()
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}.", MyMemberInfo(i).ToString(), att.Reviewed)
Console.WriteLine()
End If
Next i
End Sub
Wenn auf Methoden- oder Klassenebene keine Instanzen von DeveloperAttribute gefunden werden, benachrichtigt die GetAttribute-Methode den Benutzer, dass keine Attribute gefunden wurden, und zeigt den Namen der Methode bzw. Klasse an, die das Attribut nicht enthält. Wenn ein Attribut gefunden wird, werden das Name-Feld, das Level-Feld und das Reviewed-Feld in der Konsole angezeigt.
Mit den Membern der Type-Klasse können Sie die einzelnen Methoden und Member in der übergebenen Klasse abrufen. In diesem Beispiel wird zuerst das Type-Objekt abgefragt, um Attributinformationen für die Klassenebene abzurufen. Anschließend werden mit Type.GetMethods Instanzen aller Methoden in einem Array von System.Reflection.MemberInfo-Objekten platziert, um Attributinformationen für die Methodenebene abzurufen. Außerdem können Sie mithilfe der Type.GetProperties-Methode auf Eigenschaftenebene und mithilfe der Type.GetConstructors-Methode auf Konstruktorebene nach Attributen suchen.