Страница 266 из 502
<b>// Простой пример применения атрибута.</b>
<b>using System;</b>
<b>using System.Reflection;</b>
<b>[AttributeUsage(AttributeTargets.All)]</b>
<b>public class RemarkAttribute : Attribute {</b>
<b> string pri_remark; // базовое поле свойства Remark</b>
<b> public RemarkAttribute(string comment) {</b>
<b> pri_remark = comment;</b>
<b> }</b>
<b> public string Remark {</b>
<b> get {</b>
<b> return pri_remark;</b>
<b> }</b>
<b> }</b>
<b>}</b>
<b>[RemarkAttribute("В этом классе используется атрибут.")]</b>
<b>class UseAttrib {</b>
<b> // ...</b>
<b>}</b>
<b>class AttribDemo {</b>
<b> static void Main() {</b>
<b> Type t = typeof(UseAttrib);</b>
<b> Console.Write("Атрибуты в классе " + t.Name + ": ");</b>
<b> object[] attribs = t.GetCustomAttributes(false);</b>
<b> foreach (object о in attribs) {</b>
<b> Console.WriteLine(о);</b>
<b> }</b>
<b> Console.Write("Примечание: ");</b>
<b> // Извлечь атрибут RemarkAttribute.</b>
<b> Type tRemAtt = typeof(RemarkAttribute);</b>
<b> RemarkAttribute ra = (RemarkAttribute)</b>
<b> Attribute.GetCustomAttribute(t, tRemAtt);</b>
<b> Console.WriteLine(ra.Remark);</b>
<b> }</b>
<b>}</b>
Эта программа дает следующий результат.
<b>Атрибуты в классе UseAttrib: RemarkAttribute</b>
<b>Примечание: В этом классе используется атрибут.</b>
В предыдущем примере для инициализации атрибута RemarkAttribute его конструктору была передана символьная строка с помощью обычного синтаксиса конструктора. В этом случае параметр comment конструктора RemarkAttribute() называется позиционным. Этот термин отражает тот факт, что аргумент связан с параметром по его позиции в списке аргументов. Следовательно, первый аргумент передается первому параметру, второй аргумент — второму параметру и т.д.
Но для атрибута доступны также именованные параметры, которым можно присваивать первоначальные значения по их именам. В этом случае значение имеет имя, а не позиция параметра.
---------------------------------------
ПРИМЕЧАНИЕ
Несмотря на то что именованные параметры атрибутов, по существу, подобны именованным аргументам методов, они все же отличаются в деталях.
---------------------------------------
Именованный параметр поддерживается открытым полем или свойством, которое должно быть нестатическим и доступным только для записи. Любое поле или свойство подобного рода может автоматически использоваться в качестве именованного параметра. Значение присваивается именованному параметру с помощью соответствующего оператора, расположенного в списке аргументов при вызове конструктора атрибута. Ниже приведена общая форма объявления атрибута, включая именованные параметры.
<b>[attrib(список_позиционных_параметров,</b>
<b>именованный_параметр_1 = значение,</b>
<b>именованный_параметр_2 = значение, ...)]</b>
Первыми указываются позиционные параметры, если они существуют. Далее следуют именованные параметры с присваиваемыми значениями. Порядок следования именованных параметров особого значения не имеет. Именованным параметрам не обязательно присваивать значение, и в этом случае используется значение, устанавливаемое по умолчанию.
Применение именованного параметра лучше всего показать на конкретном примере. Ниже приведен вариант класса RemarkAttribute, в который добавлено поле Supplement, предназначенное для хранения дополнительного примечания.
<b>[AttributeUsage(AttributeTargets.All)]</b>
<b>public class RemarkAttribute : Attribute {</b>
<b> string pri_remark; // базовое поле свойства Remark</b>
<b> // Это поле можно использовать в качестве именованного параметра,</b>
<b> public string Supplement;</b>
<b> public RemarkAttribute(string comment) {</b>
<b> pri_remark = comment;</b>
<b> Supplement = "Отсутствует";</b>
<b> }</b>
<b> public string Remark {</b>
<b> get {</b>
<b> return pri_remark;</b>
<b> }</b>
<b> }</b>
<b>}</b>