Dela via


Få åtkomst till anpassade attribut

När attribut har associerats med programelement kan reflektion användas för att fråga efter deras existens och värden. .NET tillhandahåller , MetadataLoadContextsom du kan använda för att undersöka kod som inte kan läsas in för körning.

MetadataLoadContext

Det går inte att köra kod som läses in i kontexten MetadataLoadContext . Det innebär att instanser av anpassade attribut inte kan skapas, eftersom det skulle kräva att deras konstruktorer körs. Om du vill läsa in och undersöka anpassade attribut i kontexten MetadataLoadContext använder du CustomAttributeData klassen . Du kan hämta instanser av den här klassen med hjälp av lämplig överlagring av den statiska CustomAttributeData.GetCustomAttributes metoden. Mer information finns i Så här inspekterar du sammansättningsinnehåll med metadataLoadContext.

Körningskontexten

De huvudsakliga reflektionsmetoderna för att fråga attribut i körningskontexten är MemberInfo.GetCustomAttributes och Attribute.GetCustomAttributes.

Tillgängligheten för ett anpassat attribut kontrolleras med avseende på sammansättningen där det är kopplat. Detta motsvarar att kontrollera om en metod för en typ i sammansättningen där det anpassade attributet är kopplat kan anropa konstruktorn för det anpassade attributet.

Metoder som Assembly.GetCustomAttributes(Boolean) att kontrollera synligheten och tillgängligheten för typargumentet. Endast kod i sammansättningen som innehåller den användardefinierade typen kan hämta ett anpassat attribut av den typen med hjälp av GetCustomAttributes.

Följande C#-exempel är ett typiskt designmönster för anpassade attribut. Den illustrerar den anpassade attributreflektionsmodellen för körningsmiljön.

System.DLL
public class DescriptionAttribute : Attribute
{
}

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

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

Om körningen försöker hämta anpassade attribut för den offentliga anpassade attributtypen DescriptionAttribute som är kopplad till GetLanguage metoden utför den följande åtgärder:

  1. Körningen kontrollerar att typargumentet DescriptionAttribute till Type.GetCustomAttributes(Type type) är offentligt och därför är synligt och tillgängligt.
  2. Körningen kontrollerar att den användardefinierade typen MyDescriptionAttribute som härleds från DescriptionAttribute är synlig och tillgänglig i den System.Web.dll sammansättningen, där den är kopplad till metoden GetLanguage().
  3. Körningen kontrollerar att konstruktorn MyDescriptionAttribute för är synlig och tillgänglig i System.Web.dll sammansättningen.
  4. Körningen anropar konstruktorn MyDescriptionAttribute för med de anpassade attributparametrarna och returnerar det nya objektet till anroparen.

Den anpassade attributreflektionsmodellen kan läcka instanser av användardefinierade typer utanför sammansättningen där typen definieras. Detta skiljer sig inte från medlemmarna i runtime-systembiblioteket som returnerar instanser av användardefinierade typer, till exempel Type.GetMethods att returnera en matris med RuntimeMethodInfo objekt. Om du vill förhindra att en klient identifierar information om en användardefinierad anpassad attributtyp definierar du typens medlemmar som icke-offentliga.

I följande exempel visas det grundläggande sättet att använda reflektion för att få åtkomst till anpassade attribut.

using namespace System;

public ref class ExampleAttribute : Attribute
{
private:
    String^ stringVal;

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


    property String^ StringValue
    {
        String^ get() { return stringVal; }
        void set(String^ value) { stringVal = value; }
    }
};

[Example(StringValue="This is a string.")]
public ref class Class1
{
public:
    static void Main()
    {
        System::Reflection::MemberInfo^ info = Type::GetType("Class1");
        for each (Object^ attrib in info->GetCustomAttributes(true))
        {
            Console::WriteLine(attrib);
        }
    }
};

int main()
{
    Class1::Main();
}
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

Se även