Рейтинговые книги
Читем онлайн C# 4.0: полное руководство - Герберт Шилдт

Шрифт:

-
+

Интервал:

-
+

Закладка:

Сделать
1 ... 148 149 150 151 152 153 154 155 156 ... 294

  public string Supplement;

  public RemarkAttribute(string comment) {

    pri_remark = comment;

    Supplement = "Отсутствует";

  }

  public string Remark {

    get {

      return pri_remark;

    }

  }

}

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

[RemarkAttribute("В этом классе используется атрибут.",

Supplement = "Это дополнительная информация.")]

class UseAttrib {

// ...

}

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

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

// Использовать именованный параметр атрибута.

using System;

using System.Reflection;

[AttributeUsage(AttributeTargets.All)]

public class RemarkAttribute : Attribute {

  string pri_remark; // базовое поле свойства Remark

  public string Supplement; // это именованный параметр

  public RemarkAttribute(string comment) {

    pri_remark = comment;

    Supplement = "Отсутствует";

  }

  public string Remark {

    get {

      return pri_remark;

    }

  }

}

[RemarkAttribute("В этом классе используется атрибут.",

Supplement = "Это дополнительная информация.")]

class UseAttrib {

// ...

}

class NamedParamDemo {

  static void Main() {

    Type t = typeof(UseAttrib);

    Console.Write("Атрибуты в классе " + t.Name + ": ");

    object[] attribs = t.GetCustomAttributes(false);

    foreach(object o in attribs) {

      Console.WriteLine (o);

    }

    // Извлечь атрибут RemarkAttribute.

    Type tRemAtt = typeof(RemarkAttribute);

    RemarkAttribute ra = (RemarkAttribute)

    Attribute.GetCustomAttribute(t, tRemAtt);

    Console.Write("Примечание: ");

    Console.WriteLine(ra.Remark);

    Console.Write("Дополнение: ") ;

    Console.WriteLine(ra.Supplement);

  }

}

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

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

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

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

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

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

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

using System;

using System.Reflection;

[AttributeUsage(AttributeTargets.All)]

public class RemarkAttribute : Attribute {

  string pri_remark; // базовое поле свойства Remark

  public string Supplement; // это именованный параметр

  public RemarkAttribute(string comment) {

    pri_remark = comment;

    Supplement = "Отсутствует";

    Priority = 1;

  }

  public string Remark {

    get {

      return pri_remark;

    }

  }

  // Использовать свойство в качестве именованного параметра,

  public int Priority { get; set; }

}

[RemarkAttribute("В этом классе используется атрибут.",

        Supplement = " Это дополнительная информация.",

        Priority = 10)]

class UseAttrib {

// ...

}

class NamedParamDemo {

  static void Main() {

    Type t = typeof(UseAttrib);

    Console.Write("Атрибуты в классе " + t.Name + ": ");

    object[] attribs = t.GetCustomAttributes(false);

    foreach(object o in attribs) {

      Console.WriteLine(o);

    }

    // Извлечь атрибут RemarkAttribute.

    Type tRemAtt = typeof(RemarkAttribute);

    RemarkAttribute ra = (RemarkAttribute)

    Attribute.GetCustomAttribute(t, tRemAtt);

    Console.Write("Примечание: ") ;

    Console.WriteLine(ra.Remark);

    Console.Write("Дополнение: ") ;

    Console.WriteLine(ra.Supplement);

    Console.WriteLine("Приоритет: " + ra.Priority);

  }

}

Вот к какому результату приводит выполнение этого кода.

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

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

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

Приоритет: 10

В данном примере обращает на себя внимание порядок указания атрибутов перед классом UseAttrib, как показано ниже.

[RemarkAttribute("В этом классе используется атрибут.",

      Supplement = " Это дополнительная информация.",

      Priority = 10)]

class UseAttrib {

// ...

}

Именованные параметры атрибутов Supplement и Priority не обязательно указывать в каком-то определенном порядке. Порядок их указания можно свободно изменить, не меняя сами атрибуты.

И последнее замечание: тип параметра атрибута (как позиционного, так и именованного) должен быть одним из встроенных простых типов, object, Туре, перечислением или одномерным массивом одного из этих типов.

Встроенные атрибуты

В C# предусмотрено несколько встроенных атрибутов, но три из них имеют особое значение, поскольку они применяются в самых разных ситуациях. Это атрибуты AttributeUsage, Conditional и Obsolete, рассматриваемые далее по порядку.

Атрибут AttributeUsage

Как упоминалось ранее, атрибут AttributeUsage определяет типы элементов, к которым может быть применен объявляемый атрибут. AttributeUsage — это, по существу, еще одно наименование класса System.AttributeUsageAttribute. У него имеется следующий конструктор:

AttributeUsage(AttributeTargets validOn)

где validOn обозначает один или несколько элементов, к которым может быть применен объявляемый атрибут, тогда как AttributeTargets — перечисление, в котором определяются приведенные ниже значения.

1 ... 148 149 150 151 152 153 154 155 156 ... 294
На этой странице вы можете бесплатно читать книгу C# 4.0: полное руководство - Герберт Шилдт бесплатно.
Похожие на C# 4.0: полное руководство - Герберт Шилдт книги

Оставить комментарий