Мегаобучалка Главная | О нас | Обратная связь


Рефлексия. Атрибуты. Идентификация типов во время выполнения.



2019-08-13 316 Обсуждений (0)
Рефлексия. Атрибуты. Идентификация типов во время выполнения. 0.00 из 5.00 0 оценок




Атрибуты

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

Одной из задач компилятора .NET является генерирование описаний метаданных для всех типов, которые были определены, и на которые имеется ссылка в текущем проекте. Помимо стандартных метаданных, которые

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

Концепция аннотирования кода с применением атрибутов является далеко не новой. Еще в COM IDL (Interface Definition Language — язык описания интерфейсов) поставлялось множество предопределенных атрибутов, которые позволяли разработчикам описывать типы, содержащиеся внутри того или иного СОМ-сервера. Однако в СОМ атрибуты представляли собой немногим более чем просто набор ключевых слов. Когда требовалось создать специальный атрибут, разработчик в СОМ мог делать это, но затем он должен был ссылаться на этот атрибут в коде с помощью 128-битного числа (GUID-идентификатора), что, как минимум, довольно затрудняло дело.

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

Динамическая идентификация типов

Динамическая идентификация типов (RTTI) позволяет определить тип объекта во время выполнения программы. Она оказывается полезной по целому ряду причин. В частности, по ссылке на базовый класс можно довольно точно определить тип объекта, доступного по этой ссылке. Динамическая идентификация типов позволяет также проверить заранее,

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

Для поддержки динамической идентификации типов в C# предусмотрены три ключевых слова: is, as и typeof. Каждое из этих ключевых слов рассматривается далее по очереди.

Динамические типы и сборки.

Динамические сборки

C# --- Сборки .NET --- Динамические сборки

Процесс создания сложных .NET-приложений на CIL будет довольно "неблагодарным трудом". С одной стороны, CIL представляет собой чрезвычайно выразительный язык программирования, позволяющий взаимодействовать со всеми программными конструкциями, которые предусмотрены в CTS. С другой стороны, написание кода непосредственно на CIL отнимает много времени и сил и чревато допущением ошибок. И хотя знание — это всегда сила, все же наверняка интересно, насколько в действительности важно держать правила синтаксиса CIL в голове? Ответ на этот вопрос зависит от ситуации. Конечно, в большинстве случаев при программировании .NET-приложений просматривать, редактировать или создавать CIL-код совсем необязательно. Однако знание основ CIL позволяет перейти к исследованию мира динамических сборок (в отличие от статических) и оценки роли пространства имен System.Reflection.Emit.

В первую очередь может возникнуть вопрос, чем отличаются статические и динамические сборки? По определению, статической сборкой называется такой двоичный модуль .NET, который загружается прямо из хранилища на диске, т.е. на момент запроса CLR-средой он находится в физическом файле (или файлах, если сборка многофайловая) где-то на жестком диске. Как не трудно догадаться, при каждой компиляции исходного кода C# в результате всегда получается статическая сборка.

С другой стороны, динамическая сборка создается в памяти "на лету" за счет использования типов из пространства имен System.Reflection.Emit. Пространство имен System.Reflection.Emit, по сути, позволяет сделать так, чтобы сборка с ее модулями, определениями типов и логикой реализации на CIL создавалась во время выполнения. После этого сборку в памяти можно сохранять в дисковый файл, превращая ее в статическую. Несомненно, для создания динамических сборок с помощью пространства имен System.Reflection.Emit нужно разбираться в природе кодов операций CIL.

Хотя процесс создания динамических сборок является довольно сложным (и нечасто применяемым) приемом программирования, он полезен в перечисленных ниже ситуациях:

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

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

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

Некоторые компоненты механизма исполняющей среды .NET тоже предусматривают генерацию динамических сборок в фоновом режиме. Например, в ASP.NET эта технология применяется для отображения кода разметки и серверного сценария на объектную модель исполняющей среды. В LINQ код тоже может генерироваться "на лету" на основе различных выражений, содержащихся в запросах. Давайте посмотрим, какие типы предлагаются в пространстве имен System.Reflection.Emit.

Динамические типы в C#

В C# 4.0 есть средства, которые являются одновременно динамическими и статическими, а также слабо и строго типизированными. Хотя C# зарождался как статически типизированный язык, он стал динамически типизированным в любом контексте, где вы можете использовать ключевое слово dynamic, например:

 

dynamic number = 10;Console.WriteLine(number);

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

Заметьте, что C# 4.0 не заставляет вас использовать dynamic — точно так же, как C# 3.0 не вынуждал применять var, лямбды или инициализаторы объектов. C# 4.0 предоставляет новое ключевое слово dynamic специально, чтобы облегчить обработку общеизвестных случаев. Сам язык остается в основной части статически типизированным, хотя в него добавлена возможность более эффективного взаимодействия с динамическими объектами.

Зачем может понадобиться динамический объект? Во-первых, вы можете не знать тип объекта, с которым вам приходится иметь дело. Какие-то намеки у вас могут быть, но этого недостаточно для статического присваивания определенного типа данной переменной — как раз такое и случается во многих распространенных случаях, например при работе с COM-объектами или использовании отражения для получения экземпляров. В этом контексте ключевое слово dynamic снимает часть головной боли в подобных ситуациях. Код, написанный с использованием dynamic, легче читать и писать, а значит, и само приложение будет проще в понимании и сопровождении.

Во-вторых, вашему объекту может быть присуща изменчивая природа. Вы можете работать с объектами, созданными в средах динамического программирования, таких как IronPython и IronRuby. Но вы также можете задействовать эту функциональность для объектов HTML DOM (свойств expando) и Microsoft .NET Framework 4, которые изначально проектировались как динамические.

Использование dynamic

Важно понимать, что dynamic в системе типов C# является типом. У него очень специфический смысл, но это именно тип, и поэтому его нужно обрабатывать как таковой. Вы можете указать dynamic в качестве типа объявляемой вами переменной, типа элементов в наборе или возвращаемого значения метода. Кроме того, dynamic можно применять как тип параметра метода. Но использовать dynamic с оператором typeof или в качестве базового типа класса нельзя.

Следующий код показывает, как объявить динамическую переменную в теле метода:

 

public void Execute() { dynamic calc = GetCalculator(); int result = calc.Sum(1, 1);}

Если вы достаточно знаете о типе объекта, возвращаемого методом GetCalculator, то можете объявить переменную calc соответствующего типа или как var, переложив на компилятор все детали. Но применение var или явного статического типа потребовало бы от вас полной уверенности в том, что в контракте, предоставляемом типом, который возвращается GetCalculator, существует метод Sum. Если такого метода нет, вы получите ошибку компиляции.

С помощью dynamic вы откладываете любое решение о корректности выражения до периода выполнения. Код компилируется и разрешается в период выполнения, если метод Sum доступен в типе, который хранится в переменной calc.

Это ключевое слово применимо и к свойству класса. При этом вы можете дополнить этот член любым модификатором видимости — public, protected и даже static.

 

 



2019-08-13 316 Обсуждений (0)
Рефлексия. Атрибуты. Идентификация типов во время выполнения. 0.00 из 5.00 0 оценок









Обсуждение в статье: Рефлексия. Атрибуты. Идентификация типов во время выполнения.

Обсуждений еще не было, будьте первым... ↓↓↓

Отправить сообщение

Популярное:
Как построить свою речь (словесное оформление): При подготовке публичного выступления перед оратором возникает вопрос, как лучше словесно оформить свою...
Организация как механизм и форма жизни коллектива: Организация не сможет достичь поставленных целей без соответствующей внутренней...
Личность ребенка как объект и субъект в образовательной технологии: В настоящее время в России идет становление новой системы образования, ориентированного на вхождение...



©2015-2024 megaobuchalka.ru Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. (316)

Почему 1285321 студент выбрали МегаОбучалку...

Система поиска информации

Мобильная версия сайта

Удобная навигация

Нет шокирующей рекламы



(0.011 сек.)