Freigeben über


Zugreifen auf benutzerdefinierte Attribute

Nachdem Attribute programmtechnischen Elementen zugeordnet wurden, kann die Spiegelung verwendet werden, um ihr Vorhandensein und ihre Werte abzufragen. .NET stellt den MetadataLoadContextCode bereit, den Sie verwenden können, um Code zu untersuchen, der nicht für die Ausführung geladen werden kann.

MetadataLoadContext

Code, der in den MetadataLoadContext Kontext geladen wurde, kann nicht ausgeführt werden. Dies bedeutet, dass Instanzen von benutzerdefinierten Attributen nicht erstellt werden können, da dies die Ausführung ihrer Konstruktoren erfordern würde. Verwenden Sie die MetadataLoadContext Klasse, um benutzerdefinierte Attribute im CustomAttributeData Kontext zu laden und zu untersuchen. Sie können Instanzen dieser Klasse mithilfe der entsprechenden Überladung der statischen CustomAttributeData.GetCustomAttributes Methode abrufen. Weitere Informationen finden Sie unter So geht's: Assembly-Inhalte mit MetadataLoadContext inspizieren.

Der Ausführungskontext

Die wichtigsten Spiegelungsmethoden zum Abfragen von Attributen im Ausführungskontext sind MemberInfo.GetCustomAttributes und Attribute.GetCustomAttributes.

Die Zugänglichkeit eines benutzerdefinierten Attributs wird in Bezug auf die Assembly überprüft, in der es angefügt ist. Dies entspricht der Überprüfung, ob eine Methode für einen Typ in der Assembly, in der das benutzerdefinierte Attribut angefügt ist, den Konstruktor des benutzerdefinierten Attributs aufrufen kann.

Methoden wie Assembly.GetCustomAttributes(Boolean) überprüfen die Sichtbarkeit und Barrierefreiheit 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 benutzerdefiniertes Attributentwurfsmuster. Es veranschaulicht das benutzerdefinierte Laufzeit-Attributspiegelungsmodell.

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 der GetLanguage Methode zugeordnet ist, führt sie die folgenden Aktionen aus:

  1. Die Laufzeit überprüft, ob das Typargument DescriptionAttributeType.GetCustomAttributes(Type type) öffentlich ist und daher sichtbar und zugänglich ist.
  2. Die Laufzeit überprüft, ob der benutzerdefinierte Typ MyDescriptionAttribute, der von DescriptionAttribute abgeleitet wird, innerhalb der System.Web.dll-Assembly sichtbar und zugänglich ist, wo er der Methode GetLanguage() zugeordnet ist.
  3. Die Laufzeit überprüft, ob der Konstruktor von MyDescriptionAttribute in der System.Web.dll-Assembly sichtbar und zugänglich ist.
  4. Die Laufzeit ruft den Konstruktor MyDescriptionAttribute mit den benutzerdefinierten Attributparametern auf und gibt das neue Objekt an den Aufrufer zurück.

Das benutzerdefinierte Attributspiegelungsmodell könnte benutzerdefinierte Typen-Instanzen außerhalb der Assembly, in der der Typ definiert ist, offenlegen. Dies unterscheidet sich nicht von den Membern in der Laufzeitsystembibliothek, die Instanzen benutzerdefinierter Typen zurückgeben, wie z. B. Type.GetMethods, das ein Array von RuntimeMethodInfo-Objekten zurückgibt. Um zu verhindern, dass ein Client Informationen zu einem benutzerdefinierten Attributtyp entdeckt, definieren Sie die Member des Typs als nicht öffentlich.

Das folgende Beispiel veranschaulicht die grundlegende Methode der Verwendung von Spiegelung, um Zugriff auf benutzerdefinierte Attribute zu erhalten.

using System;

public class ExampleAttribute : Attribute
{
    private string stringVal;

    public ExampleAttribute()
    {
        stringVal = "This is the default string.";
    }

    public string StringValue
    {
        get { return stringVal; }
        set { stringVal = value; }
    }
}

[Example(StringValue="This is a string.")]
class Class1
{
    public static void Main()
    {
        System.Reflection.MemberInfo info = typeof(Class1);
        foreach (object attrib in info.GetCustomAttributes(true))
        {
            Console.WriteLine(attrib);
        }
    }
}
Public Class ExampleAttribute
    Inherits Attribute

    Private stringVal As String

    Public Sub New()
        stringVal = "This is the default string."
    End Sub

    Public Property StringValue() As String
        Get
            Return stringVal
        End Get
        Set(Value As String)
            stringVal = Value
        End Set
    End Property
End Class

<Example(StringValue:="This is a string.")> _
Class Class1
    Public Shared Sub Main()
        Dim info As System.Reflection.MemberInfo = GetType(Class1)
        For Each attrib As Object In info.GetCustomAttributes(true)
            Console.WriteLine(attrib)
        Next attrib
    End Sub
End Class

Siehe auch