C# 表达式树限制的机制是什么?

C# 表达式树限制的机制是什么?,c#,expression-trees,C#,Expression Trees,事实上,我希望这是可行的,但这并没有让我去寻找那张我没有看到的照片 IsSelected = (count++) % 2 == 0 这意味着: IsSelected = (count = count + 1) % 2 == 0 这就是分配发生的地方和错误的来源 根据对问题的不同回答,在.NET 4.0使用表达式的情况下,这应该是可能的,但在lambdas中不是这样。当您将任何内容传递给需要表达式的方法时,此时实际上不会计算任何内容。它所做的只是将代码分解,并从中创建一个表达式树 现在,在.

事实上,我希望这是可行的,但这并没有让我去寻找那张我没有看到的照片

IsSelected = (count++) % 2 == 0

这意味着:

IsSelected = (count = count + 1) % 2 == 0
这就是分配发生的地方和错误的来源


根据对问题的不同回答,在.NET 4.0使用表达式的情况下,这应该是可能的,但在lambdas中不是这样。

当您将任何内容传递给需要表达式的方法时,此时实际上不会计算任何内容。它所做的只是将代码分解,并从中创建一个表达式树


现在,在.NET4.0中,很多东西都添加到了表达式API中(包括并且实际上就是您正在做的事情),但是编译器(我认为这是C#编译器的一个限制)还没有更新以利用新的4.0表达式。因此,我们仅限于方法调用,赋值调用将不起作用。假设,这在将来可能会得到支持。

设想查询被远程转移到数据库。数据库引擎在执行查询时应该如何通过internet访问,并告诉计算机上的“count”变量进行自我更新?这样做没有标准的机制,因此,任何会在本地机器上变异变量的东西都不能放入将在远程机器上运行的表达式树中

更一般地说,执行时会产生副作用的查询是非常非常糟糕的查询永远不要在查询中添加副作用,即使这样做是合法的。这可能会让人非常困惑。请记住,查询不是循环的
。对象中的查询结果表示查询,而不是查询结果。执行时有副作用的查询在两次请求其结果时将执行这些副作用两次,而在零次请求结果时将执行这些副作用零次。第一部分变异变量的查询将在第二个子句执行之前变异该变量,而不是在第二个子句执行期间。因此,许多查询子句在依赖于副作用执行时会给出完全奇怪的结果。

有关这方面的更多想法,请参阅Bill Wagner的MSDN文章:

如果您正在编写LINQ to Objects查询,您可以通过压缩来执行您想要的操作:

var zipped = model.DirectTrackCampaigns.Top("10").Zip(Enumerable.Range(0, 10000), (first, second)=>new { first, second });

var res = zipped.Select(c=> new Campaign { IsSelected = c.second % 2 == 0, Name = c.first.CampaignName };
也就是说,制作一系列成对的数字和活动,然后操纵这些对


我不知道,在LINQ中,你会如何对你正在使用的任何东西做到这一点。

好吧,在.Net 4.0
表达式中是可能的,但在C#lambdas中是不可能的,即使在语言的4.0版本中也是如此。
count++
当然不会转换为
count=count+1
。后增量运算符是它自己的运算符,不会被转换为任何其他运算符。我的猜测是,该限制是经过深思熟虑的,将来将不受支持。添加这些新的表达式类型是因为DLR在内部使用它们。但它们并不用于查询,查询是C#的lambda到表达式树翻译的主要(但肯定不是唯一)用途。@svick和Linq先生(Bart De Smet)似乎都同意您的观点:“不过,目前没有改变的是对表达式树生成的语言支持。也就是说,在编写语句体lambda表达式并将其分配给表达式变量时,编译器不会使用新节点将其转换为表达式树。它继续支持LINQ所需的子集。在我们真正进入元编程领域之前,除了语言之外,我将继续使用真正的表达式树子集。“理论上,如果count是MarshallByRefObject,编译器会让它滑动,然后让运行时期望有效的远程处理配置吗?@Gabriel:问题仍然是:您将告诉SQL Server什么?不知何故,该查询必须转换为SQL并远程发送到数据库。您建议将“count++”转换为什么SQL?您可能不需要调用Zip就可以逃脱,因为将索引传递到选择器函数的方法存在过载。我可以使用查询语法调用它吗?我同意,当尝试将表达式树发送到SQL Server时,带赋值的表达式树会很糟糕。但是表达式树对于其他事情也很有用!为什么所有表达式树都受到语言的限制,而不是Linq to SQL失败并出现“赋值非法”异常?