15

我的印象是在 lambda 表达式中不可能进行赋值。例如,以下(诚然不是很有用)代码

Expression<Action<int, int>> expr = (x, y) => y = x;

产生编译器错误

An expression tree may not contain an assignment operator

然而,根据微软的文档,可以通过编程方式使用Expression.Assign. 除非我弄错了,否则以下代码会产生等效的代码Expression

ParameterExpression xparam = Expression.Parameter(typeof(int), "x");
ParameterExpression yparam = Expression.Parameter(typeof(int), "y");
BinaryExpression body = Expression.Assign(yparam, xparam);
var expr = Expression.Lambda<Action<int, int>>(body, xparam, yparam);
var cexpr = expr.Compile();

在这种情况下,编译器不会抱怨。我觉得我在这里遗漏了一些重要的区别。

4

2 回答 2

16

usr的回答是正确的;稍微扩展一下:

你没有错过一个重要的区别,你错过了一个重要的维度:时间。

如果您仔细查看文档,您会注意到该Assign节点是在 .NET 4.0 中添加的。

表达式树被添加到随 .NET 3.5 一起提供的 C# 3.0。

自 .NET 3.5 发布以来,拥有表达式树库的团队为其添加了许多功能。使用这些功能允许更多表达式位于 C# 语言的表达式树中并不能适用于 C# 4.0 或 C# 5.0。没有理由不做这个功能;这是一个非常明智的功能。但是语言设计者不需要理由不做一个功能;他们需要有理由预算花在功能上。

在这种情况下,C# 中更丰富的表达式树根本无法使其在优先级列表中足够高。如果您希望该功能具有更高的优先级,则可以在 connect.microsoft.com 上打开一个问题并提出请求。如果您为该功能提供了令人信服的场景,您的请求更有可能被实施。

于 2013-05-30T23:12:55.960 回答
10

你没有误解任何东西。C# 有意限制它可以为您生成的表达式树的种类。没有原则上的理由为什么它不能具有该功能。它只是没有投资。(创建功能会占用资源。您宁愿拥有async/await还是表达式树语句?显然第一个选项更有用。)。

从 .NET 4 开始,您也无法生成其他语句,例如ifwhile尽管它们位于表达式树 API 中。(您现在可以使用表达式树构造和编译复杂的控制流)。

于 2013-05-30T22:06:57.250 回答