Новые механизмы абстракции

После рассмотрения методов исследования типов (методов рефлексии), встает вопрос – "Какое новое качество могут принести методы рефлексии в программы. Дают ли они в руки разработчика принципиально новые возможности?" Ответ на этот вопрос положительный.

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

Формулируя алгоритм с помощью абстрактных типов данных (шаблонов), программист предполагает наличие определённых свойств у параметров шаблона – типов, которые будут "подставлены" в шаблон. Конкретная реализация алгоритма становится ясной тогда, когда становятся известны типы-параметры шаблона, т.е. во время компиляции программы, использующей шаблон – конкретизация при компиляции.

Формулируя алгоритм с помощью абстрактных (виртуальных) методов класса, разработчик откладывает окончательную реализацию алгоритма на время исполнения программы. Именно тогда, во время исполнения, решается то, какие реальные методы будут участвовать в работе алгоритма. Это зависит от того с какими конкретными объектами придётся работать алгоритму. Можно сказать, что виртуальные методы конкретизируются в runtime – конкретизация времени исполнения.

Однако возможность по виртуализации методов классов и их конкретизация во времени исполнения программы делает естественным желание получить то же и по отношению к полям объектов и к абстрактным структурам данных, когда они конкретизируются не при компиляции, а во время исполнения.

Всё это позволяет сделать Reflection. Таким образом, Reflection – это виртуализация всех элементов программы.

Теперь разработчику позволительно формулировать алгоритмы подобные таким:

1. "Найди в данной структуре поле, обозначающее цену товара, и вернуть его". Для этого перебираем все поля класса, в поисках поля типа Currency. Для этого даже не надо знать имя поля. Если известно, что поле такого типа есть и оно одно – этого достаточно.

2. "Связать поля данной структуры с аргументами требуемой хранимой процедуры на основе типов и имён полей и параметров".

3. "Вывести на консоль поля c атрибутом "видимый" (см. пример выше).

4. "Предложить пользователю выбрать класс, заполнить параметры его конструктора класса и создать экземпляр этого класса".

Таким образом, разработчику стало доступно то, что раньше мог делать только компилятор. Эти новые возможности позволяют породить совершенно новые классы алгоритмов, новые подходы к программированию, что, в свою очередь, принесёт новое качество в ваши программы.

Динамическое создание типов

Это ещё один приём программирования в среде .NET, тесно связанный с метаданными, и сулящий не менее революционные изменения в методах программирования.

Динамическое создание программного кода

Иногда требуется динамически создать некий программный код, например класс или перечисление. Естественно, что этот код будет храниться в некоторой сборке. При этом сама динамически созданная сборка может существовать только в памяти или же может быть сохранена на диске в виде файла.

Порядок создания соответствующих объектов программного кода следующий:

1. Сгенерировать сборку;

2. На основе этой сборки сгенерировать модуль;

3. На основе этого модуля сгенерировать тип (например, класс);

4. На основе этого типа (класса) сгенерировать его члены (конструкторы, методы и т.п.);

5. Выполнить непосредственное создание типа.

Ниже приведены два примера создания динамического кода – класса и перечисления.

Наши рекомендации