C#4.0:表达式树与CodeDom

c# codedom expression-trees

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

一般承认的答案

表达式树与(例如) 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方法SomeMethod1"abc"等。


codedom映射到代码 。它完全与语句等有关,与编写常规代码的方式非常相似。编码器的最常见用途是用于代码生成,作为工具的一部分。您可以将它用于动态编译,但说实话它更难。我不是粉丝。好的功能是编码树可能适用于多种语言。


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


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


总结一下:

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

热门答案

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

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



许可下: CC-BY-SA with attribution
不隶属于 Stack Overflow
许可下: CC-BY-SA with attribution
不隶属于 Stack Overflow