Некоторые атрибуты разрешается устанавливать для данного элемента всего один раз. Другие, называемые атрибутами многократного использования (multi-use attributes), могут устанавливаться несколько раз. Например, с их помощью можно установить для класса несколько различных атрибутов безопасности. В документации к атрибуту должно быть указано, является ли он атрибутом однократного или многократного использования.
В большинстве случаев бывает понятно, к какому элементу программы должен относиться атрибут. Впрочем, давайте рассмотрим следующий пример:
class Test
{
[ReturnsHResult]
public void Execute() {}
}
Обычно атрибут, находящийся в этой позиции, относится к функции класса, но в данном случае он относится к возвращаемому значению. Как же компилятор различает эти случаи?
Подобная неоднозначность возникает в нескольких ситуациях:
l функция класса/возвращаемое значение;
l событие/свойство или переменная класса;
l делегат/возвращаемое значение;
l свойство/функция доступа/возвращаемое значение функции чтения/параметр функции записи.
В каждой из этих ситуаций один из случаев встречается гораздо чаще остальных и поэтому выбирается по умолчанию. Чтобы установить атрибут для другого случая, следует указать элемент программы, к которому относится данный атрибут:
class Test
{
[return:ReturnsHResult]
public void Execute() {}
}
Строка return: означает, что атрибут относится к возвращаемому значению.
Элемент можно указать даже в том случае, если неоднозначность отсутствует. Используемые при этом идентификаторы перечислены в следующей таблице.
Идентификатор | Описание |
Assembly | Атрибут относится к сборке |
Module | Атрибут относится к модулю |
Type | Атрибут относится к классу или структуре |
Method | Атрибут относится к функции класса |
Property | Атрибут относится к свойству |
Event | Атрибут относится к событию |
Field | Атрибут относится к переменной класса |
Param | Атрибут относится к параметру |
Return | Атрибут относится к возвращаемому значению |
Атрибуты, относящиеся к сборке или модулю, должны находиться после всех директив using и до начала программного кода:
using System;
[assembly:CLSCompliant(true)]
class Test
{
Test() {}
}
В этом примере атрибут CLSCompliant устанавливается для всей сборки. Все атрибуты уровня сборки, объявленные в любом из файлов этой сборки, группируются вместе и присоединяются к сборке.
Чтобы воспользоваться стандартным атрибутом, для начала найдите конструктор, который лучше всего соответствует передаваемой информации. Затем запишите атрибут и передайте параметры конструктора. Наконец, воспользуйтесь синтаксисом именованных параметров для передачи дополнительной информации, не входящей в параметры конструктора.
Сохранение атрибутов
Существует несколько причин, по которым схема сохранения атрибутов работает не так, как было описано выше. В первую очередь это связано с быстродействием. Чтобы компилятор мог реально создать объект атрибута, в это время должна работать среда .NET Runtime, поэтому при каждой компиляции пришлось бы запускать среду, а компилятор должен был бы работать как управляемый исполняемый файл (managed executable).
Впрочем, создавать объект в действительности и не требуется, поскольку мы все равно ограничимся сохранением информации.
Следовательно, компилятор убеждается в том, что он может создать объект, вызвать конструктор и присвоить значения всех именованных параметров. Параметры атрибута заносятся в небольшой блок двоичных данных, который сохраняется вместе с метаданными объекта.
0 коммент.:
Отправить комментарий