Доступ к пользовательским атрибутам

После того как с элементами программы связаны атрибуты, можно использовать отражение для проверки их существования и получения значений. .NET предоставляет MetadataLoadContextкод, который можно использовать для проверки кода, который нельзя загрузить для выполнения.

MetadataLoadContext

Не удается выполнить код, загруженный MetadataLoadContext в контекст. Это означает, что экземпляры пользовательских атрибутов не могут быть созданы, потому что это потребует выполнения соответствующих конструкторов. Чтобы загрузить и проверить пользовательские атрибуты в контексте MetadataLoadContextCustomAttributeData , используйте класс. Экземпляры этого класса можно получить посредством использования допустимой перегрузки статического метода CustomAttributeData.GetCustomAttributes. Дополнительные сведения см. в разделе "Практическое руководство. Проверка содержимого сборки с помощью MetadataLoadContext".

Контекст выполнения

Основные методы отражения, используемые для запроса атрибутов в контексте выполнения — это MemberInfo.GetCustomAttributes и Attribute.GetCustomAttributes.

Специальные возможности настраиваемого атрибута проверка относительно сборки, в которой она подключена. Это эквивалентно проверке того, может ли метод типа в сборке, с которой связан атрибут, вызвать конструктор этого атрибута.

Такие методы, как Assembly.GetCustomAttributes(Boolean), проверяют видимость и доступность аргумента типа. Только код в сборке, содержащей определяемый пользователем тип, может получить настраиваемый атрибут этого типа с помощью GetCustomAttributes.

В следующем примере C# показан типичный способ задания пользовательского атрибута. Этот пример иллюстрирует модель отражения пользовательских атрибутов во время выполнения.

System.DLL
public class DescriptionAttribute : Attribute
{
}

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

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

Если среда выполнения пытается получить настраиваемые атрибуты для общедоступного типа настраиваемых атрибутов DescriptionAttribute , присоединенного к GetLanguage методу, он выполняет следующие действия:

  1. Среда выполнения проверка, что аргумент DescriptionAttributeType.GetCustomAttributes(Type type) типа является общедоступным, и поэтому является видимым и доступным.
  2. Среда выполнения проверка, что определяемый пользователем типMyDescriptionAttribute, производный от DescriptionAttribute этого, является видимым и доступным в сборке System.Web.dll, где он присоединен к методуGetLanguage().
  3. Среда выполнения проверка, которые MyDescriptionAttribute конструктор видим и доступен в сборке System.Web.dll.
  4. Среда выполнения вызывает конструктор с пользовательскими параметрами атрибута MyDescriptionAttribute и возвращает новый объект вызывающей объект.

Модель отражения пользовательских атрибутов может создать экземпляры определенного пользователем типа вне сборки, в которой этот тип определен. Это не отличается от элементов в системной библиотеке среды выполнения, возвращающих экземпляры определяемых пользователем типов, таких как Type.GetMethods возврат массива RuntimeMethodInfo объектов. Чтобы клиент не смог получить сведения о типе атрибута, определенном пользователем, следует описать элементы этого типа как неоткрытые.

В следующем примере показан простейший способ использования отражения для получения доступа к пользовательским атрибутам.

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

См. также