C # - Атрибуты
An attribute- это декларативный тег, который используется для передачи информации среде выполнения о поведении различных элементов, таких как классы, методы, структуры, счетчики, сборки и т. д. в вашей программе. Вы можете добавить декларативную информацию в программу с помощью атрибута. Декларативный тег обозначается квадратными скобками ([]), помещенными над элементом, для которого он используется.
Атрибуты используются для добавления в программу метаданных, таких как инструкции компилятора и другой информации, такой как комментарии, описание, методы и классы. .Net Framework предоставляет два типа атрибутов: предварительно определенные атрибуты и настраиваемые атрибуты.
Указание атрибута
Синтаксис для указания атрибута следующий:
[attribute(positional_parameters, name_parameter = value, ...)]
element
Имя атрибута и его значения указываются в квадратных скобках перед элементом, к которому применяется атрибут. Позиционные параметры определяют важную информацию, а параметры имени указывают дополнительную информацию.
Предопределенные атрибуты
.Net Framework предоставляет три предопределенных атрибута:
- AttributeUsage
- Conditional
- Obsolete
AttributeUsage
Предопределенный атрибут AttributeUsageописывает, как можно использовать класс настраиваемого атрибута. Он определяет типы элементов, к которым может применяться атрибут.
Синтаксис для указания этого атрибута следующий:
[AttributeUsage (
validon,
AllowMultiple = allowmultiple,
Inherited = inherited
)]
Куда,
Параметр validon указывает языковые элементы, на которых можно разместить атрибут. Это комбинация значений перечислителя AttributeTargets . Значение по умолчанию - AttributeTargets.All .
Параметр allowmultiple (необязательный) предоставляет значение для свойства AllowMultiple этого атрибута, логическое значение. Если это правда, атрибут многоразовый. По умолчанию - false (одноразовое).
Параметр унаследованный (необязательный) предоставляет значение для свойства Inherited этого атрибута, логическое значение. Если это правда, атрибут наследуется производными классами. Значение по умолчанию - false (не наследуется).
Например,
[AttributeUsage(
AttributeTargets.Class |
AttributeTargets.Constructor |
AttributeTargets.Field |
AttributeTargets.Method |
AttributeTargets.Property,
AllowMultiple = true)]
Условный
Этот предопределенный атрибут отмечает условный метод, выполнение которого зависит от указанного идентификатора предварительной обработки.
Это вызывает условную компиляцию вызовов методов в зависимости от указанного значения, например Debug или же Trace. Например, он отображает значения переменных при отладке кода.
Синтаксис для указания этого атрибута следующий:
[Conditional(
conditionalSymbol
)]
Например,
[Conditional("DEBUG")]
В следующем примере демонстрируется атрибут -
#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 - это логическое значение. Если его значение истинно, компилятор должен рассматривать использование элемента как ошибку. Значение по умолчанию - 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.