Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Методичка ПИ Программирование на С# _Хотов.docx
Скачиваний:
4
Добавлен:
01.07.2025
Размер:
2.22 Mб
Скачать
      1. Атрибуты в .Net

Атрибуты в .NET представляют специальные инструменты, которые позволяют встраивать в сборку дополнительные метаданные. Атрибуты могут применяться как ко всему типу (классу, интерфейсу и т.д.), так и к отдельным его частям (методу, свойству и т.д.). Основу атрибутов составляет класс System.Attribute, от которого образованы все остальные классы атрибутов.

В .NET имеется множество различных классов атрибутов. Например, при сериализации используются атрибуты [Serializable] и [NonSerialized]. С помощью рефлексии стандартные классы .NET получают использованные атрибуты и производят определенные действия. Например, атрибут[Serializable] указывает классу BinaryFormatter, что объекты с данным атрибутом можно сохранять в бинарный файл. В то ж время пока к классу с атрибутом не применена рефлексия, атрибут не размещается в памяти, и никакого влияния на данный класс не оказывает.

Создадим свой атрибут, который будет хранить роль данного класса в системе:

public class RoleInfoAttribute : System.Attribute

{

public string Name { get; set; }

public int Code { get; set; }

public RoleInfoAttribute()

{ }

public RoleInfoAttribute(string name)

{

Name = name;

}

}

По сути это обычный класс, унаследованный от System.Atribute. Теперь применим его к некоторому классу:

[RoleInfo("customer")]

public class User

{

public string Name { get; set; }

public int Age { get; set; }

public User(string n, int a)

{

Name = n;

Age = a;

}

private int Payment(int hours, int perhour)

{

return hours * perhour;

}

}

Пусть некоторый класс User применяет атрибут. Для этого имя атрибута указывается в квадратных скобках. Причем суффиксAttribute указывать необязательно. Обе записи [RoleInfo("customer")] и [RoleInfoAttribute("customer")] будут равноправны.

Если конструктор атрибута предусматривает использование параметров (public RoleInfoAttribute(string name)), то после имени атрибута мы можем указать значения для параметров конструктора. В данном случае передается значение для параметра name.

В качестве альтернативы можно использовать именованные параметры для всех свойств атрибута: [RoleInfo(Name = "customer", Code=220)]

Теперь получим с помощью рефлексии атрибут класса User:

Type t = typeof(User);

object[] attrs = t.GetCustomAttributes(false);

foreach(RoleInfoAttribute roleAttr in attrs)

{

Console.WriteLine(roleAttr.Name);

}

        1. Ограничение применения атрибута

С помощью атрибута AttributeUsage можно ограничить типы, к которым будет применяться атрибут. Например, мы хотим, чтобы выше определенный атрибут мог применяться только к классам:

[AttributeUsage(AttributeTargets.Class)]

public class RoleInfoAttribute : System.Attribute

{

//....................................

}

Ограничение задает перечисление AttributeTargets, которое может принимать еще ряд значений:

  • All: используется всеми типами

  • Assembly: атрибут применяется к сборке

  • Constructor: атрибут применяется к конструктору

  • Delegate: атрибут применяется к делегату

  • Enum: применяется к перечислению

  • Event: атрибут применяется к событию

  • Field: применяется к полю типа

  • Interface: атрибут применяется к интерфейсу

  • Method: применяется к методу

  • Property: применяется к свойству

  • Struct: применяется к структуре

С помощью логической операции ИЛИ можно комбинировать эти значения. Например, пусть атрибут может применяться к классам и структурам: [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct)]