Примечание
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
После того как атрибуты были связаны с элементами программы, отражение можно использовать для запроса их существования и значений. .NET предоставляет MetadataLoadContextкод, который можно использовать для проверки кода, который нельзя загрузить для выполнения.
MetadataLoadContext
Не удается выполнить код, загруженный в контекст MetadataLoadContext. Это означает, что нельзя создавать экземпляры пользовательских атрибутов, так как это требует выполнения конструкторов. Чтобы загрузить и проверить пользовательские атрибуты в контексте MetadataLoadContext, используйте класс CustomAttributeData. Экземпляры этого класса можно получить с помощью соответствующей перегрузки статического 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
методу, он выполняет следующие действия:
- Среда выполнения проверяет, что аргумент типа
DescriptionAttribute
дляType.GetCustomAttributes(Type type)
является общедоступным, а значит, видимым и доступным. - Среда выполнения проверяет, что определяемый пользователем тип
MyDescriptionAttribute
, производный отDescriptionAttribute
, видим и доступен в сборке System.Web.dll, к которому он прикреплен к методуGetLanguage()
. - Исполняемая среда проверяет, что конструктор
MyDescriptionAttribute
видим и доступен в сборке System.Web.dll. - Среда выполнения вызывает конструктор объекта
MyDescriptionAttribute
с пользовательскими параметрами атрибута и возвращает новый объект вызывающему.
Пользовательская модель отражения атрибутов может привести к утечке экземпляров пользовательских типов за пределы сборки, в которой определён тип. Это не отличается от элементов в системной библиотеке среды выполнения, возвращающих экземпляры определяемых пользователем типов, таких как Type.GetMethods возврат массива RuntimeMethodInfo
объектов. Чтобы предотвратить обнаружение клиентом сведений о определяемом пользователем пользовательском типе атрибута, определите элементы типа, которые должны быть неопубликованными.
В следующем примере показан базовый способ использования отражения для получения доступа к пользовательским атрибутам.
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