LINQ查询重用和延迟执行

时间:2012-07-19 16:42:48

标签: c# linq linq-to-objects

我的印象是我可以创建一个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。

3 个答案:

答案 0 :(得分:6)

当你这样做时:

source = Enumerable.Range(11, 20);

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

答案 1 :(得分:0)

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

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

找到差异;)

答案 2 :(得分: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

懒惰地访问源代码的示例(我不推荐这种类型的代码,它是如何访问lambda中的source变量创建一个可以推迟的{闭包'的示例访问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();