Важно понимать, что при применении атрибутов в коде размещающиеся внутри них метаданные, по сути, остаются бесполезными до тех пор, пока не запрашиваются явным образом в каком-то другом компоненте программного обеспечения посредством рефлексии. Если этого не происходит, они спокойно игнорируются и не причиняют никакого вреда.
Атрибуты могут использовать:
· Компилятор. Например, встретив атрибут [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;