Атрибуты в C#

Существует два типа атрибутов: Предопределенные атрибуты (идут в поставке FCL), и пользовательские атрибуты, создаваемые пользователем для добавления в код дополнительных сведений. С точки зрения разработчика оба типа имеют одинаковый синтаксис.

Пользовательский атрибут представляет собой обычный класс, унаследованный от класса Attribute. Такой атрибут может быть использован для любого метода, свойства, класса или сборки при использовании следующего синтаксиса: [ИмяАтрибута(необязательный параметр, дополнительные пары имя=значение)]

Attribute — ключевой класс при работе с атрибутами. Все системные классы-атрибуты наследуются от данного класса. При создании собственных атрибутов, также необходимо наследоваться от данного класса.

Информация, предоставляемая атрибутом, называется также метаданными. Метаданные можно анализировать в приложении во время выполнения, для того чтобы управлять тем, как это приложение осуществляет обработку данных, или до времени выполнения внешними средствами для управления обработкой и выполнением самого приложения. Например, на платформе .NET Framework предопределены и используются типы атрибутов для управления поведением времени выполнения, и некоторые языки программирования используют типы атрибутов для представления языковых функций, не поддерживаемых непосредственно общей системой типов .NET Framework.

Правила создания пользовательского атрибута:

  1. Имя атрибута должно содержать суффикс Attribute
  2. Класс-атрибут обязан наследоваться от системного класса System.Attribute
  3. Класс-атрибут обязан быть декорирован атрибутом [AttributeUsageAttribute]

Системный атрибут AttributeUsage, необходим для создания пользовательских атрибутов.

Позиционные параметры:

  • validOn – имеет тип AttributeTargets, указывает, к чему можно применять данный атрибут.

Именованные параметры:

  • AllowMultiple – имеет тип bool, разрешает или запрещает множественное применение атрибута (Значение по умолчанию — false).
  • Inherited – имеет тип bool, разрешает или запрещает наследование атрибута в производных классах (Значение по умолчанию — true).

Системный атрибут ObsoleteAttribute, позволяет отмечать устаревшие элементы системы.

Позиционные параметры:

  • message – имеет тип string, содержит строку сообщения, которая показывается при попытке использования устаревшего элемента.
  • error – имеет тип bool, если установлен в true – использование элемента, помеченного атрибутом, будет порождать ошибку на этапе компиляции.

Позиционные параметры указываются в порядке, который определяется списком параметров конструктора атрибута. Позиционные параметры всегда должны быть указаны при назначении атрибута.

Именованные параметры отсутствуют в списке параметров конструктора атрибута. Значения, задаваемые для именованных параметров, используются для инициализации полей и свойств создаваемого экземпляра атрибута. Список именованных параметров указывается через запятую после списка позиционных параметров. Каждый именованный параметр определяется как: Имя_параметра =Значение_параметра.

В C# предопределено много системных (встроенных) атрибутов, но особое значение имеют следующие три: AttributeUsage, Conditional, Obsolete.

AttributeUsage – определяет типы элементов, к которым может быть применен объявляемый атрибут, а также возможность неоднократного применения атрибута и возможность наследования атрибута производными классами. За типы элементов, к которым может быть применен атрибут отвечает позиционный параметр AttributeTargets, допустимые значения для этого перечисления можно детальнее посмотреть на MSDN. Именованный параметр AllowMultiple может принимать значения true или false и отвечает за возможность неоднократного применения атрибута. И, наконец, за возможность наследования атрибутов отвечает именованный параметр Inherited.

Conditional – позволяет создавать условные методы, которые вызываются только в том случае, если с помощью директивы #define определен конкретный идентификатор, а иначе метод пропускается. Следовательно, условный метод служит альтернативной условной компиляции по директиве #if. Для применения данного атрибута в исходный код программы следует включить пространство имен System.Diagnostics. На условные методы накладываются следующие ограничения:

  • Они должны возвращать значение типа void.
  • Должны быть членами класса или структуры, но не интерфейса.
  • Они не могут предшествовать ключевому слову override.

Obsolete – позволяет пометить элемент программы как устаревший. Существует несколько способов применения данного атрибута.

Первый выглядит так:
[Obsolete(“сообщение”)]. Применяется, когда необходимо просто пометить код, как устаревший и вывести соответствующее сообщение.

Вторая форма:
[Obsolete(“сообщение”, ошибка)]. Применяется, когда кроме вывода сообщения также необходимо запретить компиляцию.

Пример применения аттрибута Obsolete:

Пример создания пользовательского аттрибута AttributeUsage :

Пример использования пользовательского атрибута:

// Глобальные атрибуты для всей сборки.
[assembly: AssemblyVersionAttribute(«1.0.1000.0»)] // Версия сборки.
[assembly: AssemblyTitle(«AssemblySmpl»)] // Имя сборки.
[assembly: AssemblyDescription(«»)] // Описание сборки.
[assembly: AssemblyConfiguration(«»)] // Конфигурация, например, Release или Debug.
[assembly: AssemblyCompany(«nookery»)] // Имя компании разработчика.
[assembly: AssemblyProduct(«App»)] // Имя продукта.
[assembly: AssemblyCopyright(«Copyright 2018»)] // Копирайты.
[assembly: AssemblyTrademark(«»)] // Торговая марка.
[assembly: AssemblyCulture(«»)] // Какие культуры поддерживает сборка.

Рассмотрим пример того как можно разграничить уровень доступа к секретному методу, среди персонала:

Здесь мы создали пользовательский аттрибут который можем применять где угодно, но в одном экземпляре. О чем и свидетельствуют параметры, класс AccessLevelAttribute унаследован от класса Attribute. В классе имеется приватное поле означающее уровень доступа и конструктор с параметром принимающий значения.

В классе Logic мы создали метод  TopSecret к которому можно обращаться только по уровню доступа персонала. Создали 3 класса персонала и наследовались от класс Logic, так же установили атрибут перед объявлением класса, [AccessLevel(level: 0)] и значение уровня доступа. Далее мы создали массив персонала и запустили в цикле проверку на проверку доступа к методу.

Обновлено: 22.05.2019 — 15:07

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Этот сайт использует Akismet для борьбы со спамом. Узнайте, как обрабатываются ваши данные комментариев.