C# 什么';这是ExpressionType的故事。分配?

C# 什么';这是ExpressionType的故事。分配?,c#,linq,lambda,expression-trees,C#,Linq,Lambda,Expression Trees,我的印象是,在lambda表达式中,赋值是不可能的。例如,下面的代码(承认不是很有用) 然而,根据,可以使用expression.Assign以编程方式创建赋值表达式。除非我弄错了,否则以下代码将生成一个等价的表达式: ParameterExpression xparam = Expression.Parameter(typeof(int), "x"); ParameterExpression yparam = Expression.Parameter(typeof(int), "y"); Bi

我的印象是,在lambda表达式中,赋值是不可能的。例如,下面的代码(承认不是很有用)

然而,根据,可以使用
expression.Assign
以编程方式创建赋值表达式。除非我弄错了,否则以下代码将生成一个等价的
表达式

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();
ParameterExpression xparam=Expression.Parameter(typeof(int),“x”);
ParameterExpression yparam=表达式参数(typeof(int),“y”);
BinaryExpression body=Expression.Assign(yparam,xparam);
var expr=Expression.Lambda(body,xparam,yparam);
var cexpr=expr.Compile();

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

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


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

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

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

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

表达式树被添加到C#3.0中,C#3.0随.NET3.5一起提供

自.NET3.5发布以来,拥有表达式树库的团队已经为其添加了许多功能。使用这些功能允许更多表达式出现在C语言的表达式树中,这并不能满足C 4.0或C 5.0的需求。没有理由不做这个功能;这是一个非常合理的特性。但是语言设计者不需要理由就不做一个特性;他们需要一个将预算花在某个功能上的理由


在这种情况下,C#中更丰富的表达式树在优先级列表中的位置不够高。如果您希望该功能具有更高的优先级,则可以在connect.microsoft.com上打开一个问题并请求它。如果您为该功能提供了令人信服的方案,则您的请求更有可能得到实现。

编译器错误具有误导性。这意味着编译器无法为您生成代码来创建赋值(因此LINQ提供程序并不都需要支持它)。你可以自由地创建任何你想要的东西。@Gabe你应该回答这个评论。好的,这就澄清了问题。我问的原因是,似乎只有无副作用的lambda是可能的。但当我浏览表达式类型时,我看到许多改变状态的操作。对于不支持lambda的表达式类型,我还没有一个令人信服的用例,但是如果能够在一般情况下为用户定义的lambda强制执行纯度,那就太好了。@DanBarowy:最初版本中的表达式树是为无副作用的操作而设计的,因为这是LINQ所需要的,尽管它们不是100%严格的;例如,可以在表达式树中表示具有ref参数的方法。
An expression tree may not contain an assignment operator
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();