Поделиться через


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

Обновлен: Ноябрь 2007

После того как с элементами программы связаны атрибуты, можно использовать отражение для проверки их существования и получения значений. В .NET Framework версии 1.0 и 1.1 пользовательские атрибуты проверяются в контексте выполнения. Платформа .NET Framework версии 2.0 предоставляет новый контекст загрузки — контекст только для отражения, который может быть использован для проверки кода, который не может быть загружен для выполнения.

Контекст только для отражения

Код, загруженный в контекст только для отражения, не может быть выполнен. Это означает, что экземпляры пользовательских атрибутов не могут быть созданы, потому что это потребует выполнения соответствующих конструкторов. Чтобы загрузить и просмотреть пользовательские атрибуты в контексте только для отражения, используйте класс CustomAttributeData. Можно получить экземпляры этого класса посредством использования допустимой перегрузки статического метода CustomAttributeData.GetCustomAttributes. См. раздел Практическое руководство. Загрузка сборок в контекст, предназначенный только для отражения.

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

Основными методами отражения для запроса атрибутов в контексте выполнения являются System.Reflection.MemberInfo.GetCustomAttributes и System.Reflection.Assembly.GetCustomAttributes.

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

Такие методы, как System.Reflection.Assembly.GetCustomAttributes(Type, 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. Среда выполнения проверяет, является ли аргумент типа DescriptionAttribute для метода Type.GetCustomAttributes(Type type) открытым и, следовательно, видимым и доступным.

  2. Среда выполнения проверяет, является ли определенный пользователем тип MyDescriptionAttribute, производный из DescriptionAttribute, видимым и доступным в сборке System.Web.DLL, в которой он назначается методу GetLanguage().

  3. Среда выполнения проверяет, является ли конструктор атрибута MyDescriptionAttribute видимым и доступным в сборке System.Web.DLL .

  4. Среда выполнения вызывает конструктор атрибута MyDescriptionAttribute с параметрами пользовательского атрибута и возвращает в вызывающий код новый объект.

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

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

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]);
        }
    }
}

См. также

Основные понятия

Просмотр сведений о типах

Соображения о безопасности для отражения

Ссылки

MemberInfo.GetCustomAttributes

Attribute.GetCustomAttributes