这里表达式树限制的机制是什么?

时间:2011-10-05 19:56:30

标签: c# expression-trees

事实上,我希望这个工作并没有让我找到我看不到的那张照片。

enter image description here

3 个答案:

答案 0 :(得分:6)

想象一下,查询被远程转移到数据库。数据库引擎如何通过互联网到达,因为它正在执行查询并告诉"计数"您的机器上的变量是否会更新?这样做没有标准的机制,因此任何会改变本地机器上的变量的东西都不能放入在远程机器上运行的表达式树中。

更一般地说,在执行时导致副作用的查询是非常非常糟糕的查询永远不会在查询中产生副作用,即使在这样做的情况下也是合法的。这可能会非常令人困惑。请注意,查询不是for循环。查询结果对象表示查询,而不是查询结果。执行时具有副作用的查询将在两次询问结果时执行这些副作用两次,并在要求结果零次时执行零次。第一部分变量变量的查询将在第二个子句执行之前改变该变量,而不是在执行第二个子句期间。因此,许多查询子句在依赖副作用执行时会产生完全奇怪的结果。

有关此问题的更多想法,请参阅Bill Wagner关于此主题的MSDN文章:

http://msdn.microsoft.com/en-us/vcsharp/hh264182

如果您正在编写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中做到这一点,无论你如何重复使用,我都不知道。

答案 1 :(得分:2)

当您将任何内容传递给需要Expression的方法时,实际上当时没有任何内容进行评估。它所做的只是,它分解代码并从中创建一个表达式树。

现在,在.Net 4.0中,很多东西被添加到Expression API中(包括Expression.IncrementExpression.Assign,这实际上就是你正在做的事情),但是编译器(我认为它是C#编译器的限制尚未更新,以利用新的4.0表达式的东西。因此,我们仅限于方法调用,并且赋值调用将不起作用。假设,将来可以支持这一点。

答案 2 :(得分:1)

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

几乎意味着:

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

这就是分配发生的地方和错误的来源。

根据this问题的不同答案,这应该可以使用.NET 4.0使用表达式,但不能在lambdas中使用。