Подробнее об атрибутах

Некоторые атрибуты разрешается устанавливать для данного элемента всего один раз. Другие, называемые атрибутами многократного использования (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).

Впрочем, создавать объект в действительности и не требуется, поскольку мы все равно ограничимся сохранением информации.

Следовательно, компилятор убеждается в том, что он может создать объект, вызвать конструктор и присвоить значения всех именованных параметров. Параметры атрибута заносятся в небольшой блок двоичных данных, который сохраняется вместе с метаданными объекта.

Предлагаю ознакомиться с аналогичными статьями: