Сценарии динамических методов порождаемого отражения
Динамические методы, созданные с помощью класса DynamicMethod (является новым в .NET Framework версии 2.0), предоставляют расширенные возможности выпуска статических методов во врем выполнения. Динамические методы расширяют функциональные возможности типов в пространстве имен System.Reflection.Emit несколькими способами:
Они содержат меньше служебных данных, потому что отсутствует необходимость создания динамических сборок, модулей и типов для содержания методов.
В приложениях с длительным сроком выполнения они предоставляют улучшенную утилизацию ресурсов, так как память, используемая основными частями методов, может быть освобождена после завершения работы метода.
При наличии достаточных разрешений безопасности они предоставляют возможность сопоставлять код с существующей сборкой или типом, и этот код может иметь ту же видимость, что и внутренние типы или закрытые элементы.
При наличии достаточных разрешений безопасности они позволяют коду пропускать проверки видимости, выполняемые JIT-компилятором, и получать доступ к закрытым и защищенным данным объектов.
Динамические методы могут использовать объект ILGenerator для выпуска MSIL. Кроме того, динамические методы могут использовать объект DynamicILInfo для работы с маркерами метаданных и областями, в которых сложные клиенты могут выполнять собственный MSIL.
Динамические методы полезны в сценариях, в которых создание кода во время выполнения необходимо для производительности. Примеры, обсуждаемые в этом разделе, включают сериализацию, сопоставления между объектами и реляционными базами данных, регулярные выражения, частичную проверку и компиляторы для языков, нуждающихся в средах выполнения.
Простой пример создания динамического метода см. в разделе Практическое руководство. Определение и выполнение динамических методов.
Языки, которые поддерживают вызовы с поздней привязкой
Динамические методы полезны для создателей компиляторов, если тип объекта во время компиляции неизвестен. Вызовы элементов объекта должны разрешаться во время выполнения, зачастую с использованием дополнительных затрат, связанных с управлением списками аргументов. В следующем коде Visual Basic приведен этому пример.
Sub Example(ByVal obj as Object)
' ...
obj.SomeMethod(x, y, z)
' ...
End Sub
Компилятор должен создать код для поиска SomeMethod, подготовить аргументы в виде массива объектов и вызвать метод. Выполнение таких вызовов с отражением, используя метод InvokeMember, не обеспечивает хорошей производительности. Производительность можно улучшить с помощью элементов пространства имен System.Reflection.Emit для создания динамической сборки, модуля, типа и метода, однако это может привести к появлению большого рабочего набора и большей сложности кода. Динамические методы позволяют использовать более эффективную стратегию реализацию в случаях, когда сигнатура динамического метода совпадает с существующим типом делегата, так как отсутствует необходимость в создании динамической сборки, модуля или типа. Этот подход гораздо более эффективен, чем использование метода InvokeMember. Он не работает так же хорошо, как виртуальный вызов, однако требует рабочего набора меньшего объема, потому что не создает новых типов. Более того, созданный код MSIL и соответствующий машинный код могут быть удалены, если в них не будет необходимости.
Сериализация
Динамические методы могут устранить необходимость в записи пользовательского кода сериализации и десериализации. Можно отметить сериализуемый тип в соответствии с простыми правилами, а затем использовать модуль сериализации для просмотра метаданных типа. Потом создать необходимый сериализатор и десериализатор и выполнить созданный код в экземплярах типа.
При наличии достаточных разрешений безопасности модуль сериализации, реализованный с помощью динамических методов, может получить доступ к закрытым и защищенным данным для включения сериализации объектов, которые не были созданы автором модуля.
Созданные методы могут кэшироваться при частом использовании или же могут быть освобождены.
Частичная проверка
Частичная проверка, также известная как специализация программы, — это технология оптимизации алгоритмов, в которой одна или несколько входных переменных изменяются медленней, чем другие входные данные. При частичной проверке создается специализированные вызовы методов, которые обрабатывают значения медленно изменяющихся входных данных, как будто они являются константами, что позволяет использовать дополнительную оптимизацию всего алгоритма.
При помощи этой технологии часто становится возможность преобразовать низкопроизводительный алгоритм общего использования в высокоскоростной специализированный алгоритм. Рассмотрим несколько примеров.
Компиляция объекта Regex для создания программы, которая специализируется на сопоставлении определенного шаблона.
Компиляция модуля сериализации, зависящего от метаданных, в программу, которая специализируется на сериализации и десериализации определенного типа или набора типов.
Компиляция XML-схемы для создания программы, которая специализируется на проверке определенной схемы.
Компиляция преобразования XSLT в программу, которая специализируется на преобразовании XML-документа определенным способом.
Компиляция универсальной программы шифрования, которая шифрует данные с помощью специального ключа, в программу, которая оптимизирована для определенного ключа.
Динамические методы могут использоваться для реализации частичной проверки посредством создания специальных методов во время выполнения. Кроме улучшений производительности, динамические методы обеспечивают получение основных частей методов MSIL и связанного машинного кода, созданного JIT-компилятором. Это может оказаться критичным в программах, работающих в течение продолжительного периода времени.
Более подробное описание некоторых из этих сценариев см. в разделе Сценарии применения порождаемого отражения.
Создание пользовательского кода во время выполнения
Многие приложения или платформы содержат механизмы расширения, которые предоставляют пользователям возможность создавать и выполнять пользовательский код во время выполнения приложения, как правило, посредством использования предварительно определенных функций. С помощью динамических методов для создания этого кода разработчик приложения или платформы может уменьшить количество требуемых функций (и, следовательно, отпечатка памяти), а также предоставить большую гибкость для пользователей, не затрагивая при этом производительности.
См. также
Задачи
Практическое руководство. Определение и выполнение динамических методов
Ссылки
Основные понятия
Сценарии применения порождаемого отражения