我的印象是在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();
在这种情况下,编译器不会抱怨。我觉得我在这里错过了一些重要的区别。
答案 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
或表达式树语句吗?显然,第一个选项更有用。)。
您也无法生成其他语句,例如if
或while
,尽管它们 位于从.NET 4开始的表达式树API中。(您可以构造和编译复杂控件现在用表达式树流动。)