1

我的印象是我可以创建一个 LINQ 查询,然后在更改所涉及的参数时重用它。但似乎您无法更改源集合。有人可以给我一个很好的解释为什么,因为我显然误解了一些基本的东西。

这是一些示例代码。

var source = Enumerable.Range(1, 10);
var value = source.Where(x => x > 5);
var first = value.ToArray();

source = Enumerable.Range(11, 20);
var second = value.ToArray();

我期待第一个是 6,7,8,9,10,第二个是 11 到 20。

4

3 回答 3

6

当你这样做时:

source = Enumerable.Range(11, 20);

您正在创建一个新对象。但是,Where查询仍然具有对旧对象的引用。

于 2012-07-19T16:45:47.133 回答
0
source = Enumerable.Range(11, 20);
    var second = value.ToArray();

second = Enumerable.Range(11, 20);
    var second = value.ToArray();

找到不同;)

于 2012-07-19T16:52:04.373 回答
0

因为value = source.Where(x => x > 5)急切地评估 的值source,而推迟对x => x > 5部分的评估。当您重新分配源时,原始范围仍然存在,源只是指向不同的范围。简而言之,lambda 中的值是惰性求值的。

延迟执行示例

 source = Enumerable.Range(1,10).ToArray();
 value = source.Where(x => x > 5);
 var first = value.ToArray();  // 6,7,8,9,10
 source.[0] = 100;
 var second = value.ToArray(); // 100,6,7,8,9,10

懒惰访问源代码的示例(我不推荐这种类型的代码,这是一个示例,说明如何访问sourcelambda 中的变量会创建一个可以推迟访问的“闭包”source

source = Enumerable.Range(1,10);
value = Enumerable.Range(1).SelectMany(n => source.Where(x => x > 5));
var first = value.ToArray();
source = Enumerable.Range(11,20);
var second = value.ToArray();
于 2012-07-19T16:52:51.637 回答