Примечание
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Атрибуты предоставляют эффективный способ связывания метаданных или декларативной информации с кодом (сборки, типы, методы, свойства и т. д.). После связывания атрибута с сущностью программы можно запросить атрибут во время выполнения с помощью метода, называемого отражением.
Атрибуты имеют следующие свойства:
- Атрибуты добавляют метаданные в программу. метаданные — это сведения о типах, определенных в программе. Все сборки .NET содержат указанный набор метаданных, описывающий типы и члены типов, определенные в сборке. Вы можете добавить настраиваемые атрибуты, чтобы указать любые другие необходимые сведения.
- Атрибуты можно применять ко всем сборкам, модулям или небольшим элементам программы, таким как классы и свойства.
- Атрибуты могут принимать аргументы так же, как методы и свойства.
- Атрибуты позволяют программе проверять собственные метаданные или метаданные в других программах с помощью отражения.
Работа с отражением
API отражения, предоставляемые Type, описывают сборки, модули и типы. Можно использовать отражение для динамического создания экземпляра типа, привязки типа к существующему объекту или получения типа из существующего объекта и вызова методов или доступа к его полям и свойствам. При использовании атрибутов в коде отражение позволяет получить к ним доступ. Дополнительные сведения см. в разделе Атрибуты.
Вот простой пример использования метода GetType() для отражения. Все типы из Object
базового класса наследуют этот метод, который используется для получения типа переменной:
Заметка
Убедитесь, что вы добавили операторы using System;
и using System.Reflection;
в верхней части файла кода C# (.cs).
// Using GetType to obtain type information:
int i = 42;
Type type = i.GetType();
Console.WriteLine(type);
Выходные данные показывают тип:
System.Int32
В следующем примере используется отражение для получения полного имени загруженной сборки.
// Using Reflection to get information of an Assembly:
Assembly info = typeof(int).Assembly;
Console.WriteLine(info);
Результат аналогичен следующему примеру:
System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e
Различия ключевых слов для IL
Ключевые слова protected
C# и internal
не имеют значения в промежуточном языке (IL) и не используются в API отражения. Соответствующие термины в IL — это семейства и сборки. Ниже приведены некоторые способы использования следующих терминов:
- Чтобы определить
internal
метод с помощью отражения, используйте IsAssembly свойство. - Чтобы определить метод
protected internal
, используйте IsFamilyOrAssembly.
Работа с атрибутами
Атрибуты можно поместить почти в любое объявление, хотя определенный атрибут может ограничить типы объявлений, для которых он действителен. В C#можно указать атрибут, поместив имя атрибута, заключенного в квадратные скобки ([]
) над объявлением сущности, к которой она применяется.
В этом примере вы используете атрибут SerializableAttribute, чтобы применить определенную характеристику к классу:
[Serializable]
public class SampleClass
{
// Objects of this type can be serialized.
}
Можно объявить метод с атрибутом DllImportAttribute :
[System.Runtime.InteropServices.DllImport("user32.dll")]
extern static void SampleMethod();
В объявлении можно поместить несколько атрибутов:
void MethodA([In][Out] ref double x) { }
void MethodB([Out][In] ref double x) { }
void MethodC([In, Out] ref double x) { }
Некоторые атрибуты можно указать несколько раз для определенной сущности. В следующем примере показано многопользовательское использование атрибута ConditionalAttribute :
[Conditional("DEBUG"), Conditional("TEST1")]
void TraceMethod()
{
// ...
}
Заметка
По соглашению все имена атрибутов заканчиваются суффиксом "Атрибут", чтобы отличить их от других типов в библиотеках .NET. Однако при использовании атрибутов в коде не требуется указывать суффикс атрибутов. Например, [DllImport]
объявление эквивалентно [DllImportAttribute]
объявлению, но DllImportAttribute
является фактическим именем класса в библиотеке классов .NET.
Параметры атрибута
Многие атрибуты имеют параметры, которые могут быть позициональными, неназванными или именованными. В следующей таблице описывается, как работать с именованными и позиционных атрибутами:
Позиционные параметры
Параметры конструктора атрибутов:
Именованные параметры
Свойства или поля атрибута:
- Необходимо указать, нельзя пропустить
- Всегда указывайте первое
- Укажите в определенном порядке
- Всегда необязательный, опущен при значении false
- Укажите после позиционных параметров
- Укажите в любом порядке
Например, в следующем коде показаны три эквивалентных DllImport
атрибута:
[DllImport("user32.dll")]
[DllImport("user32.dll", SetLastError=false, ExactSpelling=false)]
[DllImport("user32.dll", ExactSpelling=false, SetLastError=false)]
Первый параметр, имя библиотеки DLL, является позиционным и всегда идет первым. Другие случаи — это именованные параметры. В этом сценарии оба именованных параметра по умолчанию используют значение false, поэтому они могут быть опущены. Сведения о значениях параметров по умолчанию см. в документации по отдельным атрибутам. Дополнительные сведения о разрешенных типах параметров см. в разделе Атрибуты спецификации языка C#.
Цели атрибутов
целевой атрибута — это сущность, к которой применяется атрибут. Например, атрибут может применяться к классу, методу или сборке. По умолчанию атрибут применяется к элементу, который следует за ним. Но вы также можете явно определить элемент для связывания, например метод, параметр или возвращаемое значение.
Чтобы явно определить целевой объект атрибута, используйте следующий синтаксис:
[target : attribute-list]
В следующей таблице показан список возможных target
значений.
Целевое значение | Применимо к |
---|---|
assembly |
Вся сборка |
module |
Текущий модуль сборки |
field |
Поле в классе или структуре |
event |
Событие |
method |
Метод или методы доступа к свойствам get и set |
param |
Параметры метода или параметры аксессоров свойств set |
property |
Свойство |
return |
Возвращаемое значение метода, индексатора свойств или метода доступа к свойствам get |
type |
Структура, класс, интерфейс, перечисление или делегат |
Целевое field
значение можно указать для применения атрибута к резервному полю, созданному для автоматически реализованного свойства.
В следующем примере показано, как применять атрибуты к сборкам и модулям. Дополнительные сведения см. в разделе "Общие атрибуты" (C#).
using System;
using System.Reflection;
[assembly: AssemblyTitleAttribute("Production assembly 4")]
[module: CLSCompliant(true)]
В следующем примере показано, как применять атрибуты к методам, параметрам метода и возвращаемым значениям метода в C#.
// default: applies to method
[ValidatedContract]
int Method1() { return 0; }
// applies to method
[method: ValidatedContract]
int Method2() { return 0; }
// applies to parameter
int Method3([ValidatedContract] string contract) { return 0; }
// applies to return value
[return: ValidatedContract]
int Method4() { return 0; }
Заметка
Независимо от целевых объектов, для которых атрибут ValidatedContract
считается допустимым, целевой объект return
должен быть указан, даже если атрибут ValidatedContract
определен только для применения к возвращаемым значениям. Другими словами, компилятор не использует AttributeUsage
сведения для разрешения неоднозначных целевых объектов атрибутов. Дополнительные сведения см. в разделе AttributeUsage.
Просмотр способов использования атрибутов
Ниже приведены некоторые распространенные способы использования атрибутов в коде:
- Пометьте методы контроллера, которые отвечают на сообщения POST с помощью атрибута
HttpPost
. Дополнительные сведения см. в HttpPostAttribute классе. - Описание способов маршалирования параметров метода при взаимодействии с машинным кодом. Дополнительные сведения см. в MarshalAsAttribute классе.
- Описание свойств объектной модели компонента (COM) для классов, методов и интерфейсов.
- Вызов неуправляемого кода с помощью DllImportAttribute класса.
- Опишите сборку с точки зрения названия, версии, описания или торговой марки.
- Определите, какие элементы класса следует сериализовать для обеспечения сохранности данных.
- Опишите, как сопоставить члены класса и узлы XML для сериализации XML.
- Описание требований безопасности для методов.
- Укажите характеристики, используемые для обеспечения безопасности.
- Управляйте оптимизациями с помощью JIT-компилятора, чтобы код оставался легким для отладки.
- Получение сведений о вызывающем методе.
Просмотр сценариев отражения
Отражение полезно в следующих сценариях:
- Доступ к атрибутам в метаданных программы. Дополнительные сведения см. в разделе "Получение сведений", хранящихся в атрибутах.
- Проверьте и инициализируйте типы в сборке.
- Создайте новые типы во время выполнения с помощью классов в System.Reflection.Emit пространстве имен.
- Выполните методы поздней привязки и доступа к типам, созданным во время выполнения. Дополнительные сведения см. в разделе динамической загрузки и использования типов.