Отражение. Испустите по сравнению с CodeDOM

Каковы некоторые профессионалы/недостатки для использования Отражения. Испустить библиотеку по сравнению с CodeDOM для того, чтобы динамично сгенерировать код во времени выполнения?

Я пытаюсь генерировать некоторых (относительно сложный) динамические классы в системе на основе метаданных, доступных во времени выполнения в форме XML. Я буду генерировать классы, которые расширяют существующие классы в блоке приложения, реализовывая дополнительные интерфейсы, добавляя методы, и переопределяя виртуальных и абстрактных участников.

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

48
задан LBushkin 2 March 2010 в 11:29
поделиться

3 ответа

Я думаю, что ключевые моменты о CodeDOM и Reflection.Emit следующие:

  • CodeDom генерирует исходный код C# и обычно используется при генерации кода для включения в решение и компиляции в IDE (например, классы LINQ to SQL, WSDL, XSD все работают таким образом). В этом сценарии вы также можете использовать частичные классы для настройки сгенерированного кода. Это менее эффективно, поскольку генерируется исходный код на C#, а затем запускается компилятор для его разбора (снова!) и компиляции. Вы можете генерировать код, используя относительно высокоуровневые конструкции (аналогичные выражениям и операторам C#), такие как циклы.

  • Reflection.Emit генерирует IL, поэтому он непосредственно производит сборку, которая также может храниться только в памяти. В результате это намного эффективнее. Вы должны генерировать низкоуровневый IL-код (значения хранятся на стеке; циклы должны быть реализованы с помощью переходов), поэтому генерировать любую более сложную логику немного сложно.

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

Другим вариантом может быть использование класса Expression. В .NET 4.0 он позволяет генерировать код, эквивалентный выражениям и утверждениям C#. Однако он не позволяет генерировать классы. Таким образом, вы можете объединить это с Reflection.Emit (для генерации классов, которые делегируют реализацию коду, сгенерированному с помощью Expression). Для некоторых сценариев вам также может не понадобиться полная иерархия классов - часто достаточно словаря динамически генерируемых делегатов, таких как Dictionary (но, конечно, это зависит от вашего конкретного сценария).

59
ответ дан 7 November 2019 в 12:32
поделиться

Код, ориентированный на CodeDom, как правило, легче поддерживать, поскольку вы генерируете код C #, а не IL (больше людей могут читать C #, чем IL). Более того, если вы ошиблись в коде CodeDom, вы получите ошибку компилятора; если вы генерируете недопустимый IL, вы получаете фатальное исключение или сбой.

Однако, поскольку CodeDom вызывает компилятор csc.exe , подготовка кода к использованию выполняется немного медленнее. С Reflection.Emit вы можете генерировать код прямо в памяти.

CodeDom, вероятно, подходит для большинства вещей; его используют XmlSerializer и конструктор WinForms.

16
ответ дан 7 November 2019 в 12:32
поделиться

Вы можете посмотреть ExpandoObject . Однако это только .NET 4.0.

7
ответ дан 7 November 2019 в 12:32
поделиться
Другие вопросы по тегам:

Похожие вопросы: