Добавить в цитаты Настройки чтения

Страница 267 из 502

Как видите, поле Supplement инициализируется в конструкторе символьной строкой "Отсутствует". Другого способа присвоить ему первоначальное значение в конструкторе не существует. Но поскольку поле Supplement является открытым в классе RemarkAttribute, его можно использовать в качестве именованного параметра, как показано ниже.

<b>[RemarkAttribute(&quot;В этом классе используется атрибут.&quot;,</b>

<b>Supplement = &quot;Это дополнительная информация.&quot;)]</b>

<b>class UseAttrib {</b>

<b>// ...</b>

<b>}</b>

Обратите особое внимание на вызов конструктора класса RemarkAttribute. В этом конструкторе первым, как и прежде, указывается позиционный параметр, а за ним через запятую следует именованный параметр Supplement, которому присваивается конкретное значение. И наконец, закрывающая скобка, ), завершает вызов конструктора. Таким образом, именованный параметр инициализируется в вызове конструктора. Этот синтаксис можно обобщить: позиционные параметры должны указываться в том порядке, в каком они определены в конструкторе, а именованные параметры — в произвольном порядке и вместе с присваиваемыми им значениями.

Ниже приведена программа, в которой демонстрируется применение поля Supplement в качестве именованного параметра атрибута.

<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 string Supplement; // это именованный параметр</b>

<b>  public RemarkAttribute(string comment) {</b>

<b>    pri_remark = comment;</b>

<b>    Supplement = &quot;Отсутствует&quot;;</b>

<b>  }</b>

<b>  public string Remark {</b>

<b>    get {</b>

<b>      return pri_remark;</b>

<b>    }</b>

<b>  }</b>

<b>}</b>

<b>[RemarkAttribute(&quot;В этом классе используется атрибут.&quot;,</b>

<b>Supplement = &quot;Это дополнительная информация.&quot;)]</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(&quot;Атрибуты в классе &quot; + t.Name + &quot;: &quot;);</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(&quot;Примечание: &quot;);</b>

<b>    Console.WriteLine(ra.Remark);</b>

<b>    Console.Write(&quot;Дополнение: &quot;) ;</b>

<b>    Console.WriteLine(ra.Supplement);</b>

<b>  }</b>

<b>}</b>

При выполнении этой программы получается следующий результат.

<b>Атрибуты в классе UseAttrib: RemarkAttribute</b>

<b>Примечание: В этом классе используется атрибут.</b>

<b>Дополнение: Это дополнительная информация.</b>

Прежде чем перейти к следующему вопросу, следует особо подчеркнуть, что поле pri_remark нельзя использовать в качестве именованного параметра, поскольку оно закрыто в классе RemarkAttribute. Свойство Remark также нельзя использовать в качестве именованного параметра, потому что оно доступно только для чтения. Напомним, что в качестве именованных параметров могут служить только открытые поля и свойства.

Открытое и доступное только для чтения свойство может использоваться в качестве именованного параметра таким же образом, как и открытое поле. В качестве примера ниже показано, как автоматически реализуемое свойство Priority типа int вводится в класс RemarkAttribute.

<b>// Использовать свойство в качестве именованного параметра атрибута.</b>

<b>using System;</b>

<b>using System.Reflection;</b>

<b>[AttributeUsage(AttributeTargets.All)]</b>