Г. Шилдт - С#4.0 Полное руководство (1160795), страница 107
Текст из файла (страница 107)
Это свойство содержит описание, связываемое с атрибутом. (Конечно, Невагй можно было 564 Часть 1. Язык С№ бы объявить как автоматически реализуемое свойство с закрытым аксессором яег, но ради наглядности данного примера выбрано свойство, доступное только для чтения.) В данном классе определен также один открытый конструктор, принимающий строковый аргумент и присваивающий его свойству Нева гх. Этим пока что ограничиваются функциональные возможности класса НевагИАггг1Ьпсе, готового к применению.
Присоединение атрибута Как только класс атрибута будет определен, атрибут можно присоединить к элементу. Атрибут указывается перед тем элементом, к которому он присоединяется, и для этого его конструктор заключается в квадратные скобки. В качестве примера ниже показано, как атрибут рева гКАТ Ь г1Ь обе связывается с классом. (НевагпйссгТЬпсе("В этом классе используется атрибут.")) с1аяя Пяейссг1Ь ( ) В этом фрагменте кода конструируется атрибут Нева гКАГ ГгТЬпсе, содержащии комментарий "В этом классе используется атрибут." Данный атрибутзатем связывается с классом цяеАЬ Ьг1Ь.
Присоединяя атрибут, совсем не обязательно указывать суффикс АссггЬпсе. Например, приведенный выше класс может быть объявлен следующим образом. (Вевагп("В этом классе используется атрибут.")) с1аяя Ояейссг1Ь ( ) В этом объявлении указывается только имя невагх. Такая сокращенная форма считается вполне допустимой, но все же надежнее указывать полное имя присоединяемого атрибута, чтобы избежать возможной путаницы и неоднозначности. Получение атрибутов объекта Как только атрибут будет присоединен к элементу, он может быть извлечен в других частях программы.
Для извлечения атрибута обычно используется один из двух методов. Первый метод СеГСиясовАГГгТЬпгез (), определяется в классе МевЬегТЬТо и наследуется классом Туре. Он извлекает список всех атрибутов, присоединенных к элементу. Ниже приведена одна из его форм. оЬ)есс() ОесеоясовйссггЬосея(Ьоо1 наследование) Если наследование имеет логическое значение Сгпе, то в список включаются атрибуты всех базовых классов, наследуемых по иерархической цепочке. В противном случае атрибуты извлекаются только из тех классов, которые определяются указанным типом.
Второй метод, сегспяговйггг1ьпге (), определяется в классе Агггъьпге, Ниже приведена одна из его форм: япас1с АГГг1Ьисе Весооясовйссг1Ьосе(МевЬеггпто элемент, Туре тнп атрибута) где элемент обозначает объект класса МевЬе г1п То, описывающий тот элемент, для которого создаются атрибуты, тогда как тип атрибута — требуемый атрибут. Данный метод используется в том случае, если имя получаемого атрибута известно заранее, что раааа 17. Динамическая идентификация типов, реФлексия и атрибуты 565 зачастую и бывает. Так, если в классе ПяеАССгТЬ имеется атрибут ВевагКАССг1ьпте, то для получения ссылки на этот атрибут можно воспользоваться следующей последовательностью кода.
// Получить зкяемпляр объекта класса Мевьег1пго, связанного с классом, сопержашим атрибут ВевагКАССггьоге. Туре С = Суреог(ояеяггггь)) Извлечь атрибут ВевагКАССгТЬоге. Туре СаевАСС = Суреог(певагКАССг1ьоге)) ВевагКАССггьоге га = (ВевагКАССггьпге) АССг1Ьосе.аессояговАССг1Ьпге(С, СВевАСС) Эта последовательность кода оказывается вполне работоспособной, поскольку класс Мевьег1пбо является базовым для класса Туре. Следовательно, С вЂ” это экземпляр объекта класса Мевьег1пбо.
Имея ссылку на атрибут, можно получить доступ к его членам. Благодаря этому информация об атрибуте становится доступной для программы, использующей элемент, к которому присоединен атрибут. Например, в следующей строке кода выводится содержимое свойства нева г)с. Сопяо1е Иг1Сеь1пе (га.аевагс) Ниже приведена программа, в которой все изложенные выше особенности примененил атрибутов демонстрируются на примере атрибута ВевагКАССг1ьоге. Простой пример применения атрибута.
пятна 5уягев; ояьпд 5уягев.пе11есггоп; (АссггЬосепяаче(Ассгььисетагчеся.А11)) роь11с с1аяя Вевагккссггьпсе : Ассгььссе ( ясгъпс ргг гевагкы // базовое поле свойства певал)с роЬ11с ВевагКАССгТЬоге(яггьпс сопяаепС) ( ргг гевагс = сопялепс) ) роь11с яггъпо Вевагс ( чес ( гесогп ргь гевал)сг ) ) ) (ВевагКАССг1Ьоге("В ятом классе используется атрибут.")) с1аяя ПяеягггТЬ ( // ) с1аяя АССггьбево ( ягаС1с чо1б Маьп() ( туре С = Суреоб(ояеАССг1Ь); сопяо1е.игьсе("Атрибуты з классе " + с.наше + ": ")г 566 Час)ь ). Язык О№ оЬ)еог() ассгьЬя = С.оеССоягоиАСССТЬпгев(еа1ве) г Еогеасн(оо)есс о Тп аССг1Ья) ( Сопяо1е.нг1сеььпе(о) г Сопяо1е.нг1се("Примечание: ")г г'г' Извлечь атрибут ВеиагКАСССТЬосе.
Туре СВеиАСС = Суреог(неиагКАССССЬосе)г ВеиагкАСССТЬчСе га = (ВеиагКАССгТЬосе) АССС1Ьпге.оегеоягоиАССССЬпсе(С, СяеиАСС) Сопяо1е.иг1севгпе(га.яеиагх) ) Эта программа дает следующий результат. Атрибуты в кпаппе ПвеАССг(Ь: Ввтвгсяггг1Ьосе Примечание: В ятом классе используетсв атрибут. Сравнение позиционных и именованных параметров В предыдущем примере для инициализации атрибута ВепагКАССС1Ьцге его конструктору была передана символьная строка с помощью обычного синтаксиса конструктора. В этом случае параметр сопвпепС конструктора ВеиагКАСсг1Ьцсе () называется позиционным, Эгот термин отражает тот факт, что аргумент связан с параметром по его позиции в списке аргументов.
Следовательно, первый аргумент передается первому параметру, второй аргумент — второму параметру и т.д. Но для атрибута доступны также именованные параметры, которым можно присваивать первоначальные значения по их именам. В этом случае значение имеет имя, а не позиция параметра. ПРИМЕЧАНИЕ Несмотря на то что именованные параметры атрибутов, по существу, подобны именованным аргументам методов, они асе же отличаются в деталях.
Именованный параметр поддерживается открытым полем или свойством, которое должно быть нестатическим и доступным только для записи. Любое поле или свойство подобного рода может автоматически использоваться в качестве именованного параметра. Значение присваивается именованному параметру с помощью соответствующего оператора, расположенного в списке аргументов при вызове конструктора атрибута. Ниже приведена общая форма объявления атрибута, включая именованные параметры. (асггТЬ(список позиционных параметров, именованный параметр 1 = значение, именованный параметр 2 = значение, ...)) Первыми указываются позиционные параметры, если они существуют.
Далее следуют именованные параметры с присваиваемыми значениями. Порядок следования Глава 1У. Динамическая идентиФикация типов, рефлексия н атрибуты 567 именованных параметров особого значения не имеет. Именованным параметрам не обязательно присваивать значение, и в этом случае используется значение, устанавливаемое по умолчанию. Применение именованного параметра лучше всего показать на конкретном примере.
Ниже приведен вариант класса Кевагхйг Ьг1Ьцге, в который добавлено поле Бцрр1евепг, предназначенное для хранения дополнительного примечания. (АГГг1Ьцсебааое(АГгггпцсетагоеса.л11)) рцбьтс с1ааз певал)глссг1Ьцпе : Асгг1Ьцсе ( асг1пп рг1 гевагкы // базовое поле свойства Кевагх // Это поле можно использовать а качестве именованного параметра. рцЬ11с зсггпд Борр1евепш роЬ11с Кевагхлссггпцсе(зсггпя соввепс) ( ргг гевагк = соввепг; Бцрр1евепс = "Отсутствует"; рцЬ11с асггпо Кевагк ( оег ( гегцгп ргг гевагя; ) ) ) Как видите, поле Бцрр1евепг инициализируется в конструкторе символьной строкой "отсутствует".
Другого способа присвоить ему первоначальное значение в конструкторе не существует. Но поскольку поле Бцрр1евеп С является открытым в классе кевагеАгггььцсе, его можно использовать в качестве именованного параметра, как показано ниже. (Кевагхлссггпцте("В этом классе используется атрибут.", Борр1евепс = "Это дополнительная информация.")) с1аза Овелгсг1Ь ( ) Обратите особое внимание на вызов конструктора класса Кева г)слгсг1Ьцсе.
В этом конструкторе первым, как и прежде, указывается позиционный параметр, а за ним через запятую следует именованный параметр Бцрр1евепс, которому присваивается конкретное значение. И наконец, закрывающая скобка, ), завершает вызов конструкто, ра. Таким образом, именованный параметр инициализируется в вызове конструктора.