Кафедра "ПОВТ и АС"    

 
   Главная|   Введение|   Раздел 1|   Раздел 2|   Литература|   Скачать архив (19кб)


2.Атрибуты как элементы декларативного программирования

   В общем говоря, любой компилятор может поместить информацию обо всех элементах языка в исполняемом файле (делает он это или нет, другой вопрос). Однако добавить что-либо к этой информации программист не может. Другими словами, при желании можно знать, как называется то или иное поле класса и данные какого типа оно хранит, какие методы есть у класса, но узнать из программы кто и когда последний раз редактировал метод или получить описание на русском языке назначения поля класса уже нельзя. Эта информация чаще всего относилась к категории комментариев в коде программы, которые компилятор просто пропускал. И именно эту нишу в среде .NET заняли атрибуты. Атрибуты позволяют программистам добавлять к декларации основных структурных элементов языка (сборки, классы, поля, методы, параметры методов и др.) своего рода «комментарии», - произвольно структурированные данные, определяемые в момент написания программы или программной библиотеки и сохраняемые компилятором совместно с метаданными в готовом коде. Таким образом, атрибуты существенно увеличивают возможности по использованию анализа метаданных средствами рефлексии и фактически выводят пользу от такого анализа на принципиально новый уровень. Сама среда программирования Visual Studio и компиляторы языков в среде .NET в большом объеме пользуются атрибутами для описания правил обращения с элементами программ. Например, стандартный атрибут ConditionalAttribute указывает компилятору C#, что метод помеченный этим атрибутом (а также все его вызовы) должны присутствовать в программе только в том случае, если определен специальный идентификатор, имя которого указывается в конструкторе атрибута. Если же идентификатор с таким именем на момент компиляции программы не определен, то сам метод и все его вызовы «изымаются» из кода программы, что достаточно широко используется при отладке.
   Для создания собственного атрибута необходимо описать новый класс наследник класса Attribute, определить в нем необходимые поля и свойства для хранения информации и набор конструкторов для его инициализации:

public class TrustMethodAttribute : Attribute {
private int _trustLevel;
public int TrustLevel { get { return _trustLevel; } }
public TrustMethodAttribute(int trustLevel) {
this._trustLevel = trustLevel;
}
}


   Имея готовый атрибут, можно применять его для различных элементов языка:

[TrustMethod(4)]
public void FooMethod(int param1) { … }


   Для контроля использования самого атрибута в том числе для каких элементов языка может применяться созданный атрибут и будет ли он автоматически наследоваться при его применении для пользовательских классов необходимо использовать атрибут AttributeUsageAttribute с соответствующими параметрами.
   Для анализа того, какие атрибуты применены к программной единице нужно воспользоваться методами GetCustomAttribute(s) базового абстрактного класса MemberInfo. На основании полученных данных можно принимать решения о дальнейшем поведении алгоритма. В том числе и с использованием данных, хранимых в атрибуте.

ЗАДАНИЕ 3.
   С использованием механизма рефлексии и пользовательских атрибутов выполнить один из следующих вариантов:
  1. Реализовать атрибут CommandLineAttribute с параметром CommandSwitch указывающим имя параметра командной строки программы. Атрибут должен применяться к полям и свойствам класса. Написать алгоритм разбора командной строки вида «-<имя-параметра1>[=<значение1>] …» присваивающий соответствующим полям и свойствам объекта значения параметра из командной строки. Должны поддерживаться поля и свойства логического, целочисленного и строкового типов.
  2. Реализовать алгоритм отладочной печати для объектов произвольного типа. На экран должны выдаваться строки вида <имя>=<значение>, где имя – имя общедоступного поля или свойства, помеченного атрибутом DebugPrintAttribute и хранящего значение форматной строки для значения (форматная строка по умолчанию – “{0}”).
  3. Реализовать возможность сохранения и считывания однотипных объектов из файлов данных на диске (вариант базы данных). Имя файла для каждого класса определяется атрибутом класса TableNameAttribute, поля и свойства подлежащие сохранению и считыванию должны помечаться атрибутом FieldName с указанием имени поля в файле данных. Реализовать возможность считывания как всех объектов из одного файла сразу (например в массив или список) так и обращение по порядковому номеру в файле.


   Главная|   Введение|   Раздел 1|   Раздел 2|   Литература|   Скачать архив (19кб)