Страница 268 из 502
<b>public class RemarkAttribute : Attribute {</b>
<b> string pri_remark; // базовое поле свойства Remark</b>
<b> public string Supplement; // это именованный параметр</b>
<b> public RemarkAttribute(string comment) {</b>
<b> pri_remark = comment;</b>
<b> Supplement = "Отсутствует";</b>
<b> Priority = 1;</b>
<b> }</b>
<b> public string Remark {</b>
<b> get {</b>
<b> return pri_remark;</b>
<b> }</b>
<b> }</b>
<b> // Использовать свойство в качестве именованного параметра,</b>
<b> public int Priority { get; set; }</b>
<b>}</b>
<b>[RemarkAttribute("В этом классе используется атрибут.",</b>
<b> Supplement = " Это дополнительная информация.",</b>
<b> Priority = 10)]</b>
<b>class UseAttrib {</b>
<b>// ...</b>
<b>}</b>
<b>class NamedParamDemo {</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 o in attribs) {</b>
<b> Console.WriteLine(o);</b>
<b> }</b>
<b> // Извлечь атрибут RemarkAttribute.</b>
<b> Type tRemAtt = typeof(RemarkAttribute);</b>
<b> RemarkAttribute ra = (RemarkAttribute)</b>
<b> Attribute.GetCustomAttribute(t, tRemAtt);</b>
<b> Console.Write("Примечание: ") ;</b>
<b> Console.WriteLine(ra.Remark);</b>
<b> Console.Write("Дополнение: ") ;</b>
<b> Console.WriteLine(ra.Supplement);</b>
<b> Console.WriteLine("Приоритет: " + ra.Priority);</b>
<b> }</b>
<b>}</b>
Вот к какому результату приводит выполнение этого кода.
<b>Атрибуты в классе UseAttrib: RemarkAttribute</b>
<b>Примечание: В этом классе используется атрибут.</b>
<b>Дополнение: Это дополнительная информация.</b>
<b>Приоритет: 10</b>
В данном примере обращает на себя внимание порядок указания атрибутов перед классом UseAttrib, как показано ниже.
<b>[RemarkAttribute("В этом классе используется атрибут.",</b>
<b> Supplement = " Это дополнительная информация.",</b>
<b> Priority = 10)]</b>
<b>class UseAttrib {</b>
<b>// ...</b>
<b>}</b>
Именованные параметры атрибутов Supplement и Priority не обязательно указывать в каком-то определенном порядке. Порядок их указания можно свободно изменить, не меняя сами атрибуты.
И последнее замечание: тип параметра атрибута (как позиционного, так и именованного) должен быть одним из встроенных простых типов, object, Туре, перечислением или одномерным массивом одного из этих типов.
Встроенные атрибуты
В C# предусмотрено несколько встроенных атрибутов, но три из них имеют особое значение, поскольку они применяются в самых разных ситуациях. Это атрибуты AttributeUsage, Conditional и Obsolete, рассматриваемые далее по порядку.
Как упоминалось ранее, атрибут AttributeUsage определяет типы элементов, к которым может быть применен объявляемый атрибут. AttributeUsage — это, по существу, еще одно наименование класса System.AttributeUsageAttribute. У него имеется следующий конструктор:
<b>AttributeUsage(AttributeTargets validOn)</b>
где validOn обозначает один или несколько элементов, к которым может быть применен объявляемый атрибут, тогда как AttributeTargets — перечисление, в котором определяются приведенные ниже значения.
<b>All</b>
<b>Assembly</b>
<b>Class</b>
<b>Constructor</b>
<b>Delegate</b>
<b>Enum</b>