Zugreifen auf benutzerdefinierte Attribute

Aktualisiert: November 2007

Nach der Verknüpfung von Attributen mit Programmelementen ist es möglich, ihr Vorhandensein sowie ihre Werte unter Verwendung von Reflektion abzufragen. In den .NET Framework-Versionen 1.0 und 1.1 werden benutzerdefinierte Attribute im Ausführungskontext untersucht. In .NET Framework, Version 2.0 steht ein neuer Load-Kontext, der reflektionsbezogene Kontext zur Verfügung, um Code zu untersuchen, der nicht für die Ausführung geladen werden kann.

Reflektionsbezogener Kontext

Code, der in den reflektionsbezogenen Kontext geladen wird, kann nicht ausgeführt werden. Daher können keine Instanzen benutzerdefinierter Attribute erstellt werden, da hierfür die zugehörigen Konstruktoren ausgeführt werden müssten. Benutzerdefinierte Attribute können im reflektionsbezogenen Kontext mithilfe der CustomAttributeData-Klasse geladen und untersucht werden. Sie können Instanzen dieser Klasse durch die entsprechende Überladung der statischen CustomAttributeData.GetCustomAttributes-Methode erhalten. Siehe Gewusst wie: Laden von Assemblys in den reflektionsbezogenen Kontext.

Ausführungskontext

Die wichtigsten Reflektionsmethoden zum Abfragen von Attributen im Ausführungskontext sind System.Reflection.MemberInfo.GetCustomAttributes und System.Reflection.Assembly.GetCustomAttributes.

Die Zugriffsmöglichkeit auf ein benutzerdefiniertes Attribut wird unter Berücksichtigung der Assembly geprüft, mit der es verknüpft ist. Äquivalent dazu ist die Überprüfung, ob eine Methode für einen Typ in der Assembly, mit der das benutzerdefinierte Attribut verknüpft ist, den Konstruktor des benutzerdefinierten Attributs aufrufen kann.

Methoden wie System.Reflection.Assembly.GetCustomAttributes(Type, Boolean) überprüfen die Sichtbarkeit und Verfügbarkeit des Typarguments. Nur Code in der Assembly, die den benutzerdefinierten Typ enthält, kann mithilfe von GetCustomAttributes ein benutzerdefiniertes Attribut dieses Typs abrufen.

Das folgende C#-Beispiel ist ein typisches Entwurfsmuster für ein benutzerdefiniertes Attribut. Das Beispiel verdeutlicht das Reflektionsmodell der Common Language Runtime mit benutzerdefinierten Attributen.

System.DLL
public class DescriptionAttribute : Attribute
{
}

System.Web.DLL
internal class MyDescriptionAttribute : DescriptionAttribute
{
}

public class LocalizationExtenderProvider
{
    [MyDescriptionAttribute(...)]
    public CultureInfo GetLanguage(...)
    {
    }
}

Wenn die Laufzeit versucht, die benutzerdefinierten Attribute für den öffentlichen benutzerdefinierten Attributtyp DescriptionAttribute abzurufen, der mit der GetLanguage-Methode verknüpft ist, werden folgende Aktionen durchgeführt:

  1. Common Language Runtime überprüft, ob das Typargument DescriptionAttribute für Type.GetCustomAttributes (Type Typ) öffentlich ist, d. h. sichtbar und erreichbar.

  2. Common Language Runtime überprüft, ob der von der DescriptionAttribute abgeleitete benutzerdefinierte MyDescriptionAttribute-Typ innerhalb der System.Web.DLL-Assembly sichtbar und erreichbar ist. Darin ist der MyDescriptionAttribute-Typ mit der GetLanguage()-Methode verknüpft.

  3. Common Language Runtime überprüft, ob der Konstruktor von MyDescriptionAttribute innerhalb der System.Web.DLL-Assembly sichtbar und erreichbar ist.

  4. Common Language Runtime ruft den Konstruktor von MyDescriptionAttribute mit den benutzerdefinierten Attributparametern auf und gibt das neue Objekt an den Anrufer zurück.

Durch das Reflektionsmodell mit benutzerdefinierten Attributen können Instanzen benutzerdefinierter Typen aus der Assembly verloren gehen, in der der Typ definiert ist. Dies gilt auch für Member der Laufzeitsystembibliothek, die Instanzen benutzerdefinierter Typen zurückgeben, z. B. Type.GetMethods(), wodurch die Rückgabe eines Arrays von RuntimeMethodInfo-Objekten erfolgt. Um zu verhindern, dass ein Client Informationen über einen benutzerdefinierten Attributtyp ermitteln kann, müssen Sie die Member dieses Typs als nicht öffentlich definieren.

Folgendes Beispiel zeigt, wie Reflektion im Prinzip verwendet werden kann, um Zugriff auf benutzerdefinierte Attribute zu erhalten.

Class Class1
    Public Shared Sub Main()
        Dim info As System.Reflection.MemberInfo = GetType(Class1)
        Dim attributes() As Object = info.GetCustomAttributes(True)
        For i As Integer = 0 To attributes.Length - 1
            System.Console.WriteLine(attributes(i))
        Next i
    End Sub
End Class
class MyClass 
{ 
    public static void Main() 
    {
        System.Reflection.MemberInfo info = typeof(MyClass);
        object[] attributes = info.GetCustomAttributes(true);
        for (int i = 0; i < attributes.Length; i++)
        {
            System.Console.WriteLine(attributes[i]);
        }
    }
}

Siehe auch

Konzepte

Anzeigen von Typinformationen

Sicherheitsüberlegungen für die Reflektion

Referenz

MemberInfo.GetCustomAttributes

Attribute.GetCustomAttributes