【问题标题】:Creating expression trees from lambda从 lambda 创建表达式树
【发布时间】:2012-01-09 22:27:00
【问题描述】:

我有一个 lambda 表达式:

(x) => x.Visits++

在运行时,我想把它翻译成字符串:

"set Visits = Visits + 1"

或者,如果底层数据存储不同(如 MongoDB)

{$inc: {Visits : 1}}

我认为这样做的方法是使用表达式树,但是当我将 lambda 表达式分配给表达式树时,我得到“表达式树可能不包含赋值运算符”。

除了编写一个支持更新的完整 linq 实现之外,有什么方法可以完成这个任务吗?

【问题讨论】:

  • @oleksii 在这种情况下不是,不是。如果没有Expression<...>,它将编译(作为委托); Expression<...> 不会。
  • 会有这样的帮助吗(对于 linqpad)?诠释 i = 0;函数 inc = x => ++x;函数 dec = x => --x;表达式> f = x => inc(dec(inc(x))); while(i
  • CrazyDart - 我通过为“允许的操作”定义扩展方法开始了这条路。您是对的,它使球稍微向下移动了一点-至少现在编译器会生成一个表达式。它没有那么优雅,但现在可能是一个很好的折衷方案。
  • 唉,CrazyDart - 也不支持带有语句体的表达式。对于复杂的查询,您的建议太笨拙了。不过,谢谢你的想法。

标签: c# expression-trees


【解决方案1】:

当前的 C# 编译器根本不支持这一点,而且我还没有听说 vNext 有任何变化。当然,严格来说它没有为 C# 3 / 4 定义——只有一个“在其他地方定义”(实际上,AFAIK:处理表达式树构造的规范仍然没有正式记录; 这可能是一件积极的事情,因为很难说它需要更改规范;p)。

有趣的是:从 .NET 4.0 开始,表达式树 API确实 支持变异(在这种情况下,请参阅 Expression.IncrementExpression.PostIncrementAssign) - 所以你可以 在运行时通过Expression.* 代码创建表达式树,但坦率地说,这很痛苦且难以管理。因此,这种情况有潜力发生改变,但不要抱太大希望。

还请记住 - 再次将其拉回 的表达式树分析绝非易事。可行,当然;简单:没有。

【讨论】:

  • 是的,我们从未发布过该规范,抱歉。关于表达式树 API:我们考虑过它,同时考虑支持从语句 lambda 到表达式树的转换。问题是,我们没有一个令人信服的最终用户场景,它会导致我们取消或延迟更有趣的工作(如动态或异步)。填补这些漏洞会很好,但“nice”不够引人注目。
  • 很高兴知道,tnx Mark 和 Eric。
  • 谢谢 Marc - 同意,第二步很重要,但肯定不比实现 linq 提供程序更难。我只是想要比 Linq 更轻的东西,以向我的 API 的最终用户隐藏这种复杂性,并为他们提供与底层存储提供者无关的查询格式。它看起来如此优雅,我确信它会起作用!哦,好吧。
  • @Eric 继续提供其他很棒的东西,我会原谅你的:p 同意这个规范的受众很小 - 编写新工具更好。为陈述场景找到一个很棒的例子也是难以捉摸的,同意。
猜你喜欢
  • 2023-03-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-04-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多