【发布时间】:2010-07-17 11:38:18
【问题描述】:
表达式树和 CodeDom 有什么区别? 我应该在哪种情况下使用哪个?
【问题讨论】:
标签: c# expression-trees codedom
表达式树和 CodeDom 有什么区别? 我应该在哪种情况下使用哪个?
【问题讨论】:
标签: c# expression-trees 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方法信息、1和"abc"等。
codedom 映射到 code。这都是关于语句等的,非常类似于您编写常规代码的方式。 codedom 最常见的用途是代码生成,作为工具的一部分。您可以将它用于动态编译,但说实话,它更难。我不是粉丝。一个不错的功能是代码域树可能适用于多种语言。
这里的另一个竞争者应该是DynamicMethod 和/或ILGenerator。此不映射到 AST(表达式),也不能用于生成源代码(codedom),但允许完全访问 MSIL 工具。当然,这也需要您从堆栈等方面进行思考,但它对于元编程非常高效且有效。
如果ILGenerator 太硬核,而 codedom 是 PITA,那么另一种选择是运行时生成代码作为字符串。然后通过CSharpCodeProvider 进行编译。有部分核心运行时执行此操作 (XmlSerializerIIRC)。
总结一下:
ILGenerator 或CSharpCodeProvider;在 4.0 中也是 Expression(但在 3.5 中这是非常有限的)Expression
Expression
【讨论】:
表达式树用于构建表达式。在运行时创建源代码。 CodeDom 用于编译源代码。它必须存在才能构建它。表达式树更灵活,但更难使用。
如果您想向应用程序添加脚本,请使用 CodeDom。如果你想做非常高级的反射之类的,使用表达式树,但我不推荐它。
【讨论】: