C# .NET. Атрибути. Роль атрибутів




Атрибути. Роль атрибутів. Необхідність використання атрибутів. Користувацькі атрибути


Зміст


Пошук на інших ресурсах:

1. Що таке атрибути? Навіщо у програмах використовуються атрибути?

При написанні програми програміст використовує базовий набір типів .NET а також розробляє власні типи (класи, інтерфейси, делегати, структури, зчислення). Для всіх типів з набору .NET, на які в програмі існує посилання, та власно-розроблених типів компілятор генерує відповідний опис. Цей опис має назву опис типів з допомогою метаданих.

З точки зору способу отримання, метадані можуть бути двох типів:

  • так звані стандартні метадані. Це метадані, які описують використовувані у програмі типи .NET (наприклад SteamReader, FileStream тощо) та власно розроблені типи (власні класи, інтерфейси, структури, делегати, зчислення);
  • метадані, що отримуються з використанням так званих атрибутів. Атрибути дозволяють доповнити тип (наприклад, клас) додатковими характеристиками декларативного характеру. Атрибути подібні до анотацій, які додаються до програмного коду і застосовуються до якогось конкретного елементу програми. Атрибути визначають поведінку типів, до яких вони приєднані.

З точки зору реалізації, атрибути – це спеціально розроблені класи, які є похідними від абстрактного класу System.Attribute.

Атрибути можуть застосовуватись до класів, інтерфейсів, структур, методів, властивостей, збірок модулів тощо. Якщо для деякого типу потрібно застосувати атрибут, то говорять, що потрібно приєднати атрибут. Якщо атрибут приєднано до деякого елементу (класу, методу), то цей атрибут не є членом цього класу, але він позначає додаткову інформацію, що приєднується до елементу.

У просторах імен .NET є доступними цілий ряд наперед визначених вбудованих атрибутів, які корисно застосовувати у своїх програмах. Крім того, програміст має можливість створювати власні (користувацькі) атрибути.

На рисунку 1 зображено фрагмент збірки з метаданими, що описують приєднані атрибути.

Атрибути. Доповнення збірки метаданими атрибутів

Рисунок 1. Доповнення збірки метаданими атрибутів

 

2. Створення та приєднання користувацького атрибуту. Загальна форма

Будь-який користувацький атрибут повинен бути успадкований від класу System.Attribute. У найбільш загальному випадку, створення класу-атрибуту має вигляд:

class MyClassAttribute : Attribute
{
  // ...
}

Після того, як клас атрибуту визначений, він може бути приєднаний до іншого класу. Загальна форма приєднання класу атрибуту має вигляд

[MyClassAttribute(parameters)]
class MyClass
{
  // ...
}

тут parameters – параметри конструктора класу атрибуту.

Якщо конструктор класу атрибуту не має параметрів, то загальна форма приєднання наступна

[MyClassAttribute]
class MyClass
{
  // ...
}

 

3. Вимоги та рекомендації при оголошенні класу атрибуту

Єдина вимога при створенні класу атрибуту полягає в тому, що клас повинен бути успадкований від класу System.Attribute.

Крім того, при використанні атрибутів у програмах можна визначити наступні рекомендації:

  • при оголошенні класу атрибуту, рекомендується щоб його ім’я закінчувалось суфіксом Attribute. Наприклад, MyClassVersionAttribute, MyClassCommentAttribute і т.д.;
  • якщо до деякого класу приєднується атрибут, то вказувати суфікс Attribute не обов’язково. Наприклад, якщо до класу MyClass приєднується атрибут з іменем MyClassCommentAttribute, то ім’я цього класу атрибуту можна вказати як MyClassComment прибравши суфікс Attribute. Однак, якщо суфікс не прибрати, помилки також не буде.

 

4. Створення користувацького класу атрибуту на основі іншого класу атрибуту. Успадкування атрибутів. Загальна форма

Класи атрибутів, що визначені у програмі, можуть приєднувати до себе інші класи атрибутів. У найпростішому випадку загальна форма такого приєднання наступна:

[ AnotherClassAttribute1(parameters1),
  AnotherClassAttribute2(parameters2),
  ...
  AnotherClassAttribureN(parametersN)
]
class MyClassAttribute : Attribute
{
  // ...
}

тут

  • AnotherClassAttribute1, AnotherClassAttribure2, AnotherClassAttribureN – імена класів атрибутів, які приєднуються до користувацього класу атрибуту;
  • parameters1, parameters2, parametersN – параметри конструкторів приєднуваних класів атрибутів.

Якщо до класу атрибуту приєднується тільки один клас атрибут, то загальна форма виглядає більш спрощено

[ AnotherClassAttribute(parameters) ]
class MyClassAttribute : Attribute
{
  // ...
}

 

5. Приклад створення користувацького класу-атрибуту. Отримання інформація про клас атрибуту

У прикладі демонструється створення користувацького класу атрибуту з іменем MyClassCommentAttribute. Клас атрибуту додає до елементу власний коментар (рядок). Клас атрибуту MyClassCommentAttribute приєднується до класу MyClass. У функції main() продемонстровано отримання інформації про клас атрибуту, що приєднаний до класу MyClass.

using System;

namespace ConsoleApp18
{
  // Оголошення класу атрибуту, що містить коментар
  class MyClassCommentAttribute : Attribute
  {
    private string comment; // базове поле - коментар

    // Конструктор
    public MyClassCommentAttribute(string _comment)
    {
      comment = _comment;
    }
  }

  // Оголошення класу, до якого буде приєднуватись атрибут.
  // Не обов'язково вказувати ім'я класу атрибуту.
  [MyClassCommentAttribute("This is a my class.")]
  class MyClass
  {
    // Внутрішні поля та методи класу
    // ...
  }

  class Program
  {
    static void Main(string[] args)
    {
      // Отримати атрибути класу MyClass
      // 1. Отримати дані про тип MyClass
      Type tp = typeof(MyClass);

      // 2. Отримати перелік атрибутів, які приєднані до класу MyClass
      object[] attr = tp.GetCustomAttributes(false);

      // 3. Вивести імена атрибутів, які приєднані до MyClass
      Console.WriteLine("Attributes of class MyClass:");
      foreach (object o in attr)
      {
        Console.WriteLine(o.GetType().Name);
      }
      Console.ReadKey();
    }
  }
}

У вищенаведеному коді в рядку, що передує оголошенню класу MyClass

...
[MyClassCommentAttribute("This is a my class.")]
...

викликається конструктор класу MyClassCommentAttribute, який в класі має наступне оголошення

...

class MyClassCommentAttribute : Attribute
{
  ...

  // Конструктор
  public MyClassCommentAttribute(string _comment)
  {
    comment = _comment;
  }
}

Спочатку з допомогою оператора typeof() отримується екземпляр типу System.Type, який містить дані про тип MyClass. На основі отриманого екземпляру з допомогою методу GetCustomAttributes() створюється масив класів-атрибутів, який має тип object[]. Імена отриманих класів-атрибутів виводяться в циклі foreach.

 


Зв’язані теми