ExpressionType.Assign的故事是什么?

时间:2013-05-30 21:56:32

标签: c# linq lambda expression-trees

我的印象是在lambda表达式中无法进行赋值。例如,以下(当然不是非常有用)代码

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

产生编译器错误

An expression tree may not contain an assignment operator

然而,根据Microsoft's documentation,可以使用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();

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

2 个答案:

答案 0 :(得分:16)

usr的回答是正确的;在某种程度上进行扩展:

您没有错过重要的区别,您缺少重要的维度:时间。

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

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

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

在这种情况下,C#中更丰富的表达式树只是在优先级列表上没有足够高。如果您希望该功能具有更高的优先级,那么您可以在connect.microsoft.com上打开一个问题并请求它。如果您为该功能添加了令人信服的方案,则更有可能实施您的请求。

答案 1 :(得分:11)

你不是在误解任何事情。 C#故意限制它可以为你生成的表达式树种。没有原因可以解释为什么它没有这个功能。它只是没有投资。(创建功能会占用资源。您更愿意拥有async/await或表达式树语句吗?显然,第一个选项更有用。)。

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