9

表达式树和 CodeDom 有什么区别?我应该在哪种情况下使用哪个?

4

2 回答 2

26

表达式树与(例如)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(表达式),也不能用于生成源代码(codedom),但允许完全访问 MSIL 工具。当然,它也需要您从堆栈等方面进行思考,但它对于元编程非常高效和有效。


如果ILGenerator太硬核,并且 codedom 是 PITA,那么另一种选择是将代码运行时生成为 string。然后通过它CSharpCodeProvider来编译它。核心运行时的某些部分可以执行此操作(XmlSerializerIIRC)。


所以总结一下:

  • 元编程:ILGeneratorCSharpCodeProvider;也在Expression4.0 中(但这在 3.5 中非常有限)
  • 处理 AST:Expression
  • 运行时解析:Expression
  • 多种语言的代码生成:code-dom
于 2010-07-17T21:16:00.567 回答
0

表达式树用于构建表达式。在运行时创建源代码。CodeDom 用于编译源代码。它必须存在才能构建它。表达式树更灵活,但更难使用。

如果要向应用程序添加脚本,请使用 CodeDom。如果您想做非常高级的反射之类的,请使用表达式树,但我不推荐它。

于 2010-07-17T12:49:40.820 回答