Я думаю, что ключевые моменты о 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<string, Action>
(но, конечно, это зависит от вашего точного сценария).