C#4.0:表达式树与CodeDom

时间:2010-07-17 11:38:19

标签: c# expression-trees codedom

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

2 个答案:

答案 0 :(得分:25)

表达式树与(例如)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映射到代码。所有关于语句等,非常类似于编写常规代码的方式。编码器的最常见用途是用于代码生成,作为工具的一部分。你可以使用它进行动态编译,但说实话它更难。我不是粉丝。好的功能是编码树可能适用于多种语言。


此处的另一个竞争者应该是DynamicMethod和/或ILGenerator。此映射到AST(表达式),不能用于生成源代码(codedom),但允许完全访问MSIL工具。当然,它还要求你考虑堆栈等,但它对于元编程来说是非常高效和有效。


如果ILGenerator太硬核,而且encodeom是PITA,那么另一种选择是运行时生成代码作为字符串。然后通过CSharpCodeProvider传递它来编译它。核心运行时的某些部分可以执行此操作(XmlSerializer IIRC)。


总结一下:

  • 元编程:ILGeneratorCSharpCodeProvider; 4.0中也是Expression(但这在3.5中非常有限)
  • 处理AST:Expression
  • 在运行时解析:Expression
  • 多种语言的代码生成:code-dom

答案 1 :(得分:0)

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

如果要在应用程序中添加脚本,请使用CodeDom。如果你想做非常高级的反射和喜欢,请使用表达式树,但我不推荐它。