Ответ 1
Я думаю, что ключевые моменты в CodeDOM и Reflection.Emit следующие:
-
CodeDom генерирует исходный код С# и обычно используется при создании кода, который должен быть включен как часть решения и скомпилирован в среде IDE (например, классы LINQ to SQL, WSDL, XSD все работают таким образом). В этом случае вы также можете использовать частичные классы для настройки сгенерированного кода. Он менее эффективен, потому что он генерирует источник С#, а затем запускает компилятор для его анализа (снова!) И скомпилирует его. Вы можете генерировать код, используя относительно высокоуровневые конструкции (похожие на выражения и выражения С#), такие как циклы.
-
Reflection.Emit генерирует IL, поэтому он непосредственно создает сборку, которая также может храниться только в памяти. В результате намного эффективнее. Вы должны генерировать IL-код низкого уровня (значения хранятся в стеке, цикл должен быть реализован с использованием переходов), поэтому создание более сложной логики немного сложно.
В общем, я считаю, что Reflection.Emit обычно рассматривается как предпочтительный способ генерации кода во время выполнения, в то время как CodeDOM является предпочтительным при создании кода перед компиляцией. В вашем сценарии, оба из них, вероятно, будут работать нормально (хотя CodeDOM может потребоваться более высокие привилегии, потому что на самом деле нужно вызвать С# -компилятор, который является частью любой установки .NET).
Другой вариант - использовать класс Expression
. В .NET 4.0 он позволяет генерировать код, эквивалентный выражениям и операторам С#. Однако это не позволяет создавать классы. Таким образом, вы можете комбинировать это с Reflection.Emit(для создания классов, которые делегируют реализацию в код, сгенерированный с помощью Expression
). Для некоторых сценариев вам также может не понадобиться полноценная иерархия классов - часто словарь динамически сгенерированных делегатов, таких как Dictionary<string, Action>
, может быть достаточно хорошим (но, конечно, это зависит от вашего точного сценария).