Учебно-методический комплекс общее количество часов 58 ч. Лекции 28 ч


Использование пользовательских атрибутов


Download 2.46 Mb.
bet80/91
Sana19.10.2023
Hajmi2.46 Mb.
#1709453
TuriУчебно-методический комплекс
1   ...   76   77   78   79   80   81   82   83   ...   91
Bog'liq
Язык программирования C#

18.4. Использование пользовательских атрибутов

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


[AuthorAttribute("tsalik", DeveloperPosition = "Programmer", Level = 1)]


class Program
{
static void Main(string[] args)
{
}
}
Лист. 9.7

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


[AuthorAttribute("alish", DeveloperPosition = "Programmer", Level = 1)]


[AuthorAttribute("alish", Level = 1, DeveloperPosition = "Programmer")]
Лист. 9.8


18.5. Доступ к информации, хранящейся в атрибутах

И пользовательские, и встроенные атрибуты предоставляют заключенную в них информацию на этапе выполнения посредствам механизма отражений. Т.е информацию, хранящуюся в атрибуте можно получить только из уже готовой сборки. Чтобы использовать механизм отражений необходимо подключить пространство имен System.Reflection.


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

[AuthorAttribute("mike", DeveloperPosition = "Developer", Level = 2)]


[AuthorAttribute("tsalik", DeveloperPosition = "Coder", Level = 1)]
[AuthorAttribute("jack", DeveloperPosition = "Coder", Level = 1)]
[Obsolete("Слишком старый класс!", false)]
class Client
{
[Obsolete("Необходимо сменить тип счетчика.", false)]
[AuthorAttribute("mike", DeveloperPosition = "Developer", Level = 2)]
byte Counter;

[AuthorAttribute("mike", DeveloperPosition = "Developer", Level = 2)]


static bool Good;

[Obsolete("Необходимо обновить конструктор.", false)]


public Client()
{
}

[AuthorAttribute("mike", DeveloperPosition = "Developer", Level = 2)]


void Buy(double Price)
{
}
}
Лист. 9.9

Теперь с помощью механизма отражений получим информацию, содержащуюся в атрибутах класса и его методов. Сначала напишем метод для обработки информации из атрибутов. Мы воспользовались в классе Client только двумя типами атрибутов: AuthorAttribute и ObsoleteAttribute. Следовательно, только их и будем обрабатывать.


// вывод атрибутов некоторой сущности


static void OutputEssenceAtributes(Attribute[] EssenceAtributes)
{
foreach (System.Attribute attr in EssenceAtributes)
{
// очередной атрибут из массива имеет тип AuthorAttribute
if (attr is AuthorAttribute)
{
AuthorAttribute a = (AuthorAttribute)attr;
Console.WriteLine("Разработчик: ");
Console.WriteLine("Имя:{0} Статус:{1} Доступ:{2}",
a.Name, a.Position, a.Level);
}
// очередной атрибут из массива имеет тип ObsoleteAttribute
if (attr is ObsoleteAttribute)
{
ObsoleteAttribute a = (ObsoleteAttribute)attr;
Console.WriteLine("Сообщение: {0}", a.Message);
}
}
}
Лист. 9.10

Метод получает массив атрибутов некоторой сущности. Элементы массива имеют разный тип, но в этом методе обрабатываются только те элементы, что имеют типы AuthorAttribute или ObsoleteAttribute. Значения, хранимые в этих атрибутах, и выводятся на консоль.


Теперь создадим главный метод Main() нашей программы, который и будет вызывать OutputEssenceAtributes для класса Client и для всех его членов. Здесь нам придется затронуть механизм рефлексий.

static void Main(string[] args)


{
// создаем объект из которго будем получать информацию для отражений
Client OurClient = new Client();
Type T = OurClient.GetType();

// получаем отрибуты класса


System.Attribute[] attrs = System.Attribute.GetCustomAttributes(T);
// проходим по всем атрибутам класса
Console.WriteLine("Класс имеет следующие атрибуты:");
OutputEssenceAtributes(attrs);

// получаем информацию о членах класса, объявленных нами


MemberInfo[] Members =
T.GetMembers(BindingFlags.Public | BindingFlags.NonPublic |
BindingFlags.GetField | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly);
// проходим по всем членам класса
foreach (MemberInfo mem in Members)
{
Console.WriteLine("Член класса {0} имеет следующие атрибуты:", mem.Name);
attrs = System.Attribute.GetCustomAttributes(mem);
OutputEssenceAtributes(attrs);
}
}
Лист. 9.11

В первом блоке листинга мы создаем объект класса Client и получаем из этого объекта информацию его типе. На этой информации основана вся работа механизма отражений.


// создаем объект из которго будем получать информацию для отражений


Client OurClient = new Client();
Type T = OurClient.GetType();
Лист. 9.12

Затем мы получаем массив атрибутов всего класса. Для этого используется статический метод Attribute.GetCustomAttributes(), у этого метода имеются 16 перегрузок, но мы воспользуемся самой простой, которая возвращает массив Attribute[], содержащий все атрибуты класса. Далее этот массив передается методу OutputEssenceAtributes().


// получаем отрибуты класса


System.Attribute[] attrs = System.Attribute.GetCustomAttributes(T);
// проходим по всем атрибутам класса
Console.WriteLine("Класс имеет следующие атрибуты:");
OutputEssenceAtributes(attrs);
Лист. 9.13

В последнем блоке мы выводим всю информацию о членах класса. Для этого мы воспользуемся экземплярными методом GetMembers() класса Type. Он получает в качестве параметра комбинацию из флагов перечисления BindingFlags. В нашем случае эта комбинация построена так, чтобы получить все члены класса, кроме унаследованных. Метод GetMembers() возвращает массив объектов класса MemberInfo, содержащий информацию о членах класса или объекта. Далее мы проходим по всем элементам этого массива и выводим их атрибуты. Для этого используется другая перегрузка метода Attribute.GetCustomAttributes(), которая получает в качестве параметра объект MemberInfo.


foreach (MemberInfo mem in Members)


{
Console.WriteLine("Член класса {0} имеет следующие атрибуты:", mem.Name);
attrs = System.Attribute.GetCustomAttributes(mem);
OutputEssenceAtributes(attrs);
}
Лист. 9.14

Вывод программы:


Класс имеет следующие атрибуты:


Разработчик:
Имя:jack Статус:Coder Доступ:1
Сообщение: Слишком старый класс!
Разработчик:
Имя:mike Статус:Developer Доступ:2
Разработчик:
Имя:tsalik Статус:Coder Доступ:1
Член класса Buy имеет следующие атрибуты:
Разработчик:
Имя:mike Статус:Developer Доступ:2
Член класса .ctor имеет следующие атрибуты:
Сообщение: Необходимо обновить конструктор.
Член класса Counter имеет следующие атрибуты:
Сообщение: Необходимо сменить тип счетчика.
Разработчик:
Имя:mike Статус:Developer Доступ:2
Член класса Good имеет следующие атрибуты:
Разработчик:
Имя:mike Статус:Developer Доступ:2
Вывод. 9.1



Download 2.46 Mb.

Do'stlaringiz bilan baham:
1   ...   76   77   78   79   80   81   82   83   ...   91




Ma'lumotlar bazasi mualliflik huquqi bilan himoyalangan ©fayllar.org 2024
ma'muriyatiga murojaat qiling