Атрибути - це додаткові відомості про елементи програми (класів, методів, параметрів і т. д.). За допомогою атрибутів можна додавати інформацію в метаданні збірки і потім витягувати її під час виконання програми. Атрибут є спеціальним видом класу і походить від базового класу System. Attribute.
Атрибути діляться на стандартні і призначених для користувача. У бібліотеці .NET передбачена множина стандартних атрибутів, які можна використовувати в програмах. Якщо всієї різноманітності стандартних атрибутів не вистачить, щоб задовольнити вимоги програміста, він може описати власні класи атрибутів, після чого застосовувати їх точно так, як і стандартні.
При використанні (специфікації) атрибутів вони задаються в секції атрибутів, що розташовується безпосередньо перед елементом, для опису якого вони призначені. Секція береться в квадратні дужки і може містити декілька атрибутів, що перераховуються через кому. Порядок проходження атрибутів довільний.
Для кожного атрибуту задаються ім'я, а також необов'язкові параметри і тип елементу збірки, до якого відноситься атрибут. Простий приклад атрибуту:
[Serializable]
class Monster{
[NonSerialized]
string name;
int health, ammo;}
Атрибут [Serializable] означає, що об'єкти цього класу можна зберігати в зовнішній пам'яті, відноситься до всього класу Monster. При цьому поле name помічене атрибутом [Nonserialized] говорить про те, що це поле зберігатися не повинно.
Зазвичай з контексту зрозуміло, до якого елементу збірки відноситься атрибут, проте в деяких випадках можуть виникнути неоднозначності. Для їх усунення перед ім'ям атрибуту записується тип елементу збірки - уточнююче ключове слово, відокремлюване від атрибуту двокрапкою. Ключові слова і відповідні елементи збірки, до яких можуть відноситися атрибути наведені в таблиці 12.3.
Таблиця 12.3
Типи елементу збірки, що задаються для атрибутів
Ключове слово
| Опис
|
assembly
| Атрибут відноситься до всієї збірки
|
field
| Атрибут відноситься до поля
|
event
| Атрибут відноситься до події
|
method
| Атрибут відноситься до методу
|
param
| Атрибут відноситься до параметрів методу
|
property
| Атрибут відноситься до властивості
|
return
| Атрибут відноситься до повертає мого значення
|
type
| Атрибут відноситься до класу або структури
|
Нехай, наприклад, перед методом описаний гіпотетичний атрибут ABC:
[ABC]
public void Do() { ... }
За умовчанням він відноситься до методу. Щоб вказати, що атрибут відноситься не до методу, а до його поверємого значення, слід написати:
[return:ABC]
public void Do() { ... }
Атрибут може мати параметри. Вони записуються в круглих дужках через кому після імені атрибуту і бувають позиційними і іменованими. Іменований параметр указується у формі ім'я = значення, для позиційного просто задається значення. Наприклад, для використаного в наступному фрагменті коди атрибуту ClsСompliant заданий позиційний параметр true. Атрибути, що відносяться до збірки, повинні розташовуватися безпосередньо після директив using, наприклад:
using System;
[assembly:CLSCompliant(true)]
namespace ConsoleApplicationl
{
...
}
Атрибут [CLSCompliant] визначає, задовольняє програмний код угодам CLS (Common Language Specification) чи ні. Стандартні атрибути, як і інші типи класів, мають набір конструкторів, які визначають, яким чином використовувати (специфікувати) атрибут. Фактично, при використанні атрибуту указується найбільш відповідний конструктор, а величини, невказані в конструкторі, задаються через іменовані параметри в кінці списку параметрів.
Стандартний атрибут [Stathread], старанно видалений зі всіх лістингів в цій книзі, відноситься до методу, перед яким він записаний. Він має значення тільки для додатків, що використовують модель СОМ, і задає модель потоків в рамках моделі СОМ. Приклад застосування ще одного стандартного атрибуту, [Conditional], приведений далі в розділі “Директиви препроцесора”.
Атрибути рівня збірки зберігаються у файлі AssemblyInfo.cs, автоматично створюваному середовищем для будь-якого проекту. Для явного завдання номера версії збірки можна записати атрибут [AssemblyVersion], наприклад:
[assembly: AssemblyVersion("1.0.0.0")]