Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Прога - ответы2.docx
Скачиваний:
19
Добавлен:
23.04.2019
Размер:
206.38 Кб
Скачать

Потребители атрибутов

Важно понимать, что при применении атрибутов в коде размещающиеся внутри них метаданные, по сути, остаются бесполезными до тех пор, пока не запрашиваются явным образом в каком-то другом компоненте программного обеспечения посредством рефлексии. Если этого не происходит, они спокойно игнорируются и не причиняют никакого вреда.

Атрибуты могут использовать:

  • Компилятор. Например, встретив атрибут [Obsolete], компилятор отобразит соответствующее предупреждение в окне Error List.

  • Библиотечные классы. К примеру, метод Serialize() класса BinaryFormatter определит класс, отмеченный атрибутом [Serializable], как подлежащий сохранению в двоичном виде.

  • Среда CLR. Например, чтобы можно было получать доступ к методу посредством HTTP-запросов, а его возвращаемое значение автоматически преобразовывалось в формат XML, понадобится применить к этому методу атрибут [WebMethod], а обо всех остальных деталях будет заботиться CLR-среда.

  • Специальные утилиты, помогающие при разработке, отладке, исследовании программ.

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

Применение атрибутов

Рассмотрим применение атрибутов на примере сериализации. Предположим, требуется создать класс Point, который можно было бы сохранять в двоичном формате. Для этого достаточно применить к определению этого класса атрибут [Serializable]. Если в классе есть какое-то поле, которое не должно сохраняться, к нему должен быть применен атрибут [NonSerialized].

// Этот класс может сохраняться на диске

[Serializable]

class Point : Shape

{

// Это поле сохраняться не будет

[NonSerialized]

uint _color;

double _x;

double _y;

}

Действие атрибута распространяется только на элемент сразу же после него, поэтому, например, [NonSerialized] будет действовать только на _color.

К одному элементу можно применять сразу несколько атрибутов. При этом равноценными будут записи

[NonSerialized]

[Obsolete("Do not use this field")]

uint _color;

и

[NonSerialized, Obsolete("Do not use this field")]

uint _color;

Сокращенное именование атрибутов

На самом деле по соглашению атрибуты имеют суффикс Attribute, но его можно опускать при использовании в коде. Поэтому в действительности класс, реализующий атрибут [NonSerialized] , имеет имя NonSerializedAttribute, и равноценными будут записи

[NonSerialized]

uint _color;

и

[NonSerializedAttribute]

uint _color;

Создание собственных атрибутов:

Пример:

class ShapeDescriptionAttribute: System.Attribute

{

// свойство

public string Description { get; set; }

// конструкторы

public ShapeDescriptionAttribute() { }

public ShapeDescriptionAttribute(string description)

{

Description = description;

}

}

Как видно, атрибут – обычный класс, только унаследованный от System.Attribute.

Применение собственных атрибутов:

Пример:

[ShapeDescription("Точка на плоскости")]

class Point : Shape

{

double _x;

double _y;

};

[ShapeDescription(Description = "Окружность на плоскости")]

class Circle : Shape

{

Point _center;

double _radius;

}

В первом случае используется инициализация через конструктор атрибута, во втором —так называемый синтаксис именованных атрибутов. Для него нужно, чтобы в классе атрибута были доступные для записи свойства (как, например Description).