LINQ查询重用和延迟执行(LINQ query reuse and deferred execut

2019-07-30 11:55发布

我是,我可以创造一个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。

Answer 1:

当你这样做:

source = Enumerable.Range(11, 20);

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



Answer 2:

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

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

查找差异;)



Answer 3:

因为value = source.Where(x => x > 5)热切评估的值source ,但是推迟所述的评价x => x > 5的一部分。 当你重新分配源,原来的范围仍然存在,源只是指向不同的范围。 总之,拉姆达内的值被懒惰地评估。

的延迟执行的示例

 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

访问源懒惰地 (ⅰ不会推荐这种类型的代码的一个例子 ,它是如何访问的示例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();


文章来源: LINQ query reuse and deferred execution