【问题标题】:A lambda expression with a statement body cannot be converted to an expression tree带有语句体的 lambda 表达式不能转换为表达式树
【发布时间】:2013-05-08 21:19:02
【问题描述】:

StackOverlow 上有几个关于语句体表达式的问题。我只是想知道为什么在 C# 中不可能做到这一点? (没有在编译器中实现的复杂性在哪里?)

有来自@eric-lippert 的great explanation for memberof/infoof。语句体表达式转换有类似的解释吗?

更新(基于 Jon Skeet 的回答):

我的用例是在运行时轻松转换 C# 代码转换的可能性。我只是想知道大量的努力在哪里?编译器应该已经在编译过程中构建了一些类似的表达式树——或者像 infoof 的情况下是否存在隐藏的复杂性?

【问题讨论】:

    标签: c# .net compiler-construction design-decisions


    【解决方案1】:

    表达式树最初是为 LINQ 创建的,它是关于 查询。查询通常是基于函数的,因此单表达式 lambda 非常适合,无需担心表达式树等内的控制流。我怀疑将任意语句 lambda 的表达式树转换为 SQL 等将是愚蠢的差事。

    表达式树后来针对 .NET 4 进行了增强(我相信主要是为了 DLR),但 C# 4 编译器实际上并不需要为此从 lambda 表达式创建复杂的表达式树 - 所以主要是那里只是没有足够的好处让它值得。

    换句话说:您的用例是什么,可以证明包含它可能需要付出大量努力?也许这样的用例,也许在未来的 C# 版本中,团队会认为这是值得的。但目前,能够将表达式 lambda 转换为表达式树有一个明显的好处 - 但为语句 lambda 做同样的额外努力并没有相应的好处。

    编辑:C# 编译器绝对没有理由需要代码的表达式树表示(就System.Linq.Expressions 而言),但它有一个抽象语法树。

    我怀疑您真正想要的是Roslyn - 它仍在 CTP 中,但它基本上是一个编译器 API。 Roslyn AST 并非设计用于与表达式树相同的场景,但如果您对编译器转换感兴趣,它可能仍然是您想要的。

    【讨论】:

    • AST 和 .NET 表达式的区别在哪里?将 AST 转换为另一棵树(在本例中为 .NET 表达式)并不费力,不是吗?因为从我(用户)的角度来看,缺少一小部分? -- 大部分工作已经完成了,还是没有?
    • 但我理解你的原因:对于 LINQ 用户来说更复杂,额外的工作并没有太多好处。 - 据我了解,与 infoof 不同,它们可能不是隐藏的复杂性。 (所以,我应该在 Roslyn 可用之前使用 NRefactory。)
    • @TN.:老实说,我怀疑从 Roslyn AST 转换为表达式树是相当大的工作量。我建议您尝试一下并找出答案:)
    • Roslyn 团队考虑使用“语句”表达式树(此外:回想起来,称它们为表达式树显然是一个错误;它们应该是“代码树”,因为“语句表达式树”不有意义)作为内部实现细节或外部格式,并拒绝两者。它们不包含使 Roslyn 正常工作所需的所有信息,而且改造它们会很昂贵。
    猜你喜欢
    • 2011-07-07
    • 1970-01-01
    • 1970-01-01
    • 2013-08-08
    • 2016-06-01
    • 2012-01-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多