C# 4.0: Деревья выражений по сравнению с CodeDom

Каковы различия между Деревьями выражений и CodeDom? Который я должен использовать для который сценарий?

9
задан Yaron Naveh 17 July 2010 в 11:38
поделиться

2 ответа

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

((a + 2) / b)

это:

ParameterExpression a = ..., b = ...
var body = Expression.Divide(
    Expression.Add(a, Expression.Constant(2)),
    b);
var lambda = Expression.Lambda(body,a,b); // optionally with generics

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

Еще одно ключевое использование выражений заключается в том, что вы можете деконструировать их во время выполнения, так что в вашем коде вы можете иметь:

Foo(x => x.SomeMethod(1, "abc"));

и извлечь SomeMethod метод-инфо, 1 и "abc" и т.д.


codedom отображается на code. Это все об утверждениях и т.д., очень похоже на то, как вы пишете обычный код. Чаще всего codedom используется для генерации кода, как часть инструментария. Вы можете использовать его для динамической компиляции, но, честно говоря, это сложнее. Я не фанат. Приятной особенностью является то, что дерево кода может работать для нескольких языков.


Другим претендентом здесь должен быть DynamicMethod и/или ILGenerator. Это не отображает AST (выражение), и не может быть использовано для генерации исходного кода (кодедом), но позволяет получить полный доступ к инструментам MSIL. Конечно, это также требует, чтобы вы мыслили в терминах стеков и т.д., но это очень эффективно и результативно для мета-программирования.


Если ILGenerator - это слишком сложно, а кодогенерация - это хлопотно, то другой вариант - это генерация кода как строки во время выполнения. Затем передать его через CSharpCodeProvider для компиляции. Есть части ядра среды выполнения, которые делают это (XmlSerializer IIRC).


Итак, подведем итоги:

  • мета-программирование: ILGenerator или CSharpCodeProvider; также Expression в 4.0 (но это довольно ограничено в 3.5)
  • обработка AST: Expression
  • парсинг во время выполнения: Expression
  • генерация кода на нескольких языках: code-dom
25
ответ дан 4 December 2019 в 08:32
поделиться

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

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

0
ответ дан 4 December 2019 в 08:32
поделиться
Другие вопросы по тегам:

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