Учебники

C # — Атрибуты

Атрибут — это декларативный тег, который используется для передачи во время выполнения информации о поведении различных элементов, таких как классы, методы, структуры, перечислители, сборки и т. Д. В вашей программе. Вы можете добавить декларативную информацию в программу, используя атрибут. Декларативный тег обозначается квадратными ([]) скобками, помещенными над элементом, для которого он используется.

Атрибуты используются для добавления метаданных, таких как инструкции компилятора, и другой информации, такой как комментарии, описание, методы и классы, в программу. .Net Framework предоставляет два типа атрибутов: предопределенные атрибуты и настраиваемые атрибуты.

Указание атрибута

Синтаксис для указания атрибута следующий:

[attribute(positional_parameters, name_parameter = value, ...)]
element

Имя атрибута и его значения указываются в квадратных скобках перед элементом, к которому применяется атрибут. Позиционные параметры определяют основную информацию, а параметры имени определяют необязательную информацию.

Предопределенные атрибуты

.Net Framework предоставляет три предопределенных атрибута —

  • AttributeUsage
  • условный
  • устарелый

AttributeUsage

Предопределенный атрибут AttributeUsage описывает, как можно использовать пользовательский класс атрибута. Он указывает типы элементов, к которым может быть применен атрибут.

Синтаксис для указания этого атрибута следующий:

[AttributeUsage (
   validon,
   AllowMultiple = allowmultiple,
   Inherited = inherited
)]

Куда,

  • Параметр validon указывает элементы языка, на которых можно разместить атрибут. Это комбинация значения перечислителя AttributeTargets . Значением по умолчанию является AttributeTargets.All .

  • Параметр allowmultiple (необязательный) предоставляет значение для свойства AllowMultiple этого атрибута, логическое значение. Если это правда, атрибут является multiuse. По умолчанию используется значение false (одноразовое использование).

  • Унаследованный параметр (необязательный) предоставляет значение для свойства Inherited этого атрибута, логическое значение. Если это правда, атрибут наследуется производными классами. Значением по умолчанию является false (не наследуется).

Параметр validon указывает элементы языка, на которых можно разместить атрибут. Это комбинация значения перечислителя AttributeTargets . Значением по умолчанию является AttributeTargets.All .

Параметр allowmultiple (необязательный) предоставляет значение для свойства AllowMultiple этого атрибута, логическое значение. Если это правда, атрибут является multiuse. По умолчанию используется значение false (одноразовое использование).

Унаследованный параметр (необязательный) предоставляет значение для свойства Inherited этого атрибута, логическое значение. Если это правда, атрибут наследуется производными классами. Значением по умолчанию является false (не наследуется).

Например,

[AttributeUsage(
   AttributeTargets.Class |
   AttributeTargets.Constructor |
   AttributeTargets.Field |
   AttributeTargets.Method |
   AttributeTargets.Property, 
   AllowMultiple = true)]

условный

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

Это вызывает условную компиляцию вызовов методов, в зависимости от указанного значения, такого как Debug или Trace . Например, он отображает значения переменных при отладке кода.

Синтаксис для указания этого атрибута следующий:

[Conditional(
   conditionalSymbol
)]

Например,

[Conditional("DEBUG")]

В следующем примере демонстрируется атрибут —

Live Demo

#define DEBUG
using System;
using System.Diagnostics;

public class Myclass {
   [Conditional("DEBUG")]
   
   public static void Message(string msg) {
      Console.WriteLine(msg);
   }
}
class Test {
   static void function1() {
      Myclass.Message("In Function 1.");
      function2();
   }
   static void function2() {
      Myclass.Message("In Function 2.");
   }
   public static void Main() {
      Myclass.Message("In Main function.");
      function1();
      Console.ReadKey();
   }
}

Когда приведенный выше код компилируется и выполняется, он дает следующий результат —

In Main function
In Function 1
In Function 2

устарелый

Этот предопределенный атрибут отмечает программный объект, который не должен использоваться. Это позволяет вам сообщить компилятору об отмене определенного целевого элемента. Например, когда в классе используется новый метод, и если вы все еще хотите сохранить старый метод в классе, вы можете пометить его как устаревший, отобразив сообщение, что следует использовать новый метод вместо старого.

Синтаксис для указания этого атрибута следующий:

[Obsolete (
   message
)]

[Obsolete (
   message,
   iserror
)]

Куда,

  • Сообщение параметра — это строка, описывающая причину, по которой элемент устарел, и что вместо этого использовать.

  • Параметр iserror , является логическим значением. Если его значение равно true, компилятор должен рассматривать использование элемента как ошибку. Значением по умолчанию является false (компилятор выдает предупреждение).

Сообщение параметра — это строка, описывающая причину, по которой элемент устарел, и что вместо этого использовать.

Параметр iserror , является логическим значением. Если его значение равно true, компилятор должен рассматривать использование элемента как ошибку. Значением по умолчанию является false (компилятор выдает предупреждение).

Следующая программа демонстрирует это —

using System;

public class MyClass {
   [Obsolete("Don't use OldMethod, use NewMethod instead", true)]
   
   static void OldMethod() {
      Console.WriteLine("It is the old method");
   }
   static void NewMethod() {
      Console.WriteLine("It is the new method"); 
   }
   public static void Main() {
      OldMethod();
   }
}

Когда вы пытаетесь скомпилировать программу, компилятор выдает сообщение об ошибке:

 Don't use OldMethod, use NewMethod instead

Создание пользовательских атрибутов

.Net Framework позволяет создавать пользовательские атрибуты, которые могут использоваться для хранения декларативной информации и могут быть получены во время выполнения. Эта информация может быть связана с любым целевым элементом в зависимости от критериев проектирования и потребностей приложения.

Создание и использование пользовательских атрибутов включает четыре шага:

  • Объявление пользовательского атрибута
  • Построение пользовательского атрибута
  • Примените пользовательский атрибут к целевому элементу программы
  • Доступ к атрибутам через отражение

Последний шаг включает в себя написание простой программы для чтения метаданных для поиска различных обозначений. Метаданные — это данные о данных или информация, используемая для описания других данных. Эта программа должна использовать отражения для доступа к атрибутам во время выполнения. Об этом мы поговорим в следующей главе.

Объявление пользовательского атрибута

Новый пользовательский атрибут должен быть производным от класса System.Attribute . Например,

//a custom attribute BugFix to be assigned to a class and its members
[AttributeUsage(
   AttributeTargets.Class |
   AttributeTargets.Constructor |
   AttributeTargets.Field |
   AttributeTargets.Method |
   AttributeTargets.Property,
   AllowMultiple = true)]

public class DeBugInfo : System.Attribute

В предыдущем коде мы объявили пользовательский атрибут с именем DeBugInfo .

Построение пользовательского атрибута

Давайте создадим пользовательский атрибут с именем DeBugInfo , который хранит информацию, полученную в результате отладки любой программы. Пусть он хранит следующую информацию —

  • Кодовый номер для ошибки
  • Имя разработчика, который выявил ошибку
  • Дата последнего просмотра кода
  • Строковое сообщение для хранения замечаний разработчика

Класс DeBugInfo имеет три частных свойства для хранения первых трех сведений и открытое свойство для хранения сообщения. Следовательно, номер ошибки, имя разработчика и дата проверки являются позиционными параметрами класса DeBugInfo, а сообщение является необязательным или именованным параметром.

Каждый атрибут должен иметь хотя бы один конструктор. Позиционные параметры должны быть переданы через конструктор. Следующий код показывает класс DeBugInfo

//a custom attribute BugFix to be assigned to a class and its members
[AttributeUsage(
   AttributeTargets.Class |
   AttributeTargets.Constructor |
   AttributeTargets.Field |
   AttributeTargets.Method |
   AttributeTargets.Property,
   AllowMultiple = true)]

public class DeBugInfo : System.Attribute {
   private int bugNo;
   private string developer;
   private string lastReview;
   public string message;
   
   public DeBugInfo(int bg, string dev, string d) {
      this.bugNo = bg;
      this.developer = dev;
      this.lastReview = d;
   }
   public int BugNo {
      get {
         return bugNo;
      }
   }
   public string Developer {
      get {
         return developer;
      }
   }
   public string LastReview {
      get {
         return lastReview;
      }
   }
   public string Message {
      get {
         return message;
      }
      set {
         message = value;
      }
   }
}

Применение пользовательского атрибута

Атрибут применяется, помещая его непосредственно перед его целью —

[DeBugInfo(45, "Zara Ali", "12/8/2012", Message = "Return type mismatch")]
[DeBugInfo(49, "Nuha Ali", "10/10/2012", Message = "Unused variable")]
class Rectangle {
   //member variables
   protected double length;
   protected double width;
   public Rectangle(double l, double w) {
      length = l;
      width = w;
   }
   [DeBugInfo(55, "Zara Ali", "19/10/2012", Message = "Return type mismatch")]
   
   public double GetArea() {
      return length * width;
   }
   [DeBugInfo(56, "Zara Ali", "19/10/2012")]
   
   public void Display() {
      Console.WriteLine("Length: {0}", length);
      Console.WriteLine("Width: {0}", width);
      Console.WriteLine("Area: {0}", GetArea());
   }
}

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