怀疑

问题描述:

假设我有这样的:怀疑

IEnumerable<MyObject> StructsTemp; 

我写了一篇关于StructsTemp N次查询,所以它从DB填充,等等。 后来,我执行他们呼吁.ToList()

IList<MyObject> StructsFinal = StructsTemp.ToList(); 
... some queries on StructsFinal .... 
StructsTemp = StructsFinal; 

那么如果后来我做到这一点?

StructsTemp.Count() 

它会重新执行StructsTemp上的n个查询吗?这会重新执行StructsTemp.ToList()吗?这会重新执行StructsFinal上的所有查询吗?

如果您分配的List<T>给变量StructsTemp参考,IEnumerable<T> actually一个List<T>,将使用它的Count属性,而不是列举的基本序列。

var numbers = new []{ 1,2,3 }; 
IEnumerable<int>evenNumbers = numbers.Where(i=> i % 2 == 0); 
// deferred, will enumerate the sequence to count the even numbers 
int count = evenNumbers.Count(); 
evenNumbers = evenNumbers.ToList(); 
// not deferred, using the Count property of List<T> 
count = evenNumbers.Count(); 

因此,后者将始终返回相同的值,因为它将保留在新的集合中。当底层集合发生变化时(例如,numbers.Remove(2)导致evenNumbers.Count为0),前者可以在每次迭代时返回不同的结果。

编辑

下面是行为的一个更有意义的演示:http://ideone.com/91Yrh

+0

so evenNumbers = evenNumbers.ToList();将“变成”一个IEnumerable到列表? :O我不这么认为... – markzzz 2012-07-20 12:11:21

+0

@markzzz:'IList '实现'IEnumerable '因此每​​个列表也是隐式的可枚举。这只是继承。但是,引用从具有基础集合的linq查询更改为不同的'List '。 – 2012-07-20 12:17:50

+0

这是不明确的:)假设,在int count = evenNumbers.Count();'I“之前循环”evenNumbers与foreach:那是什么?不是列表:O – markzzz 2012-07-20 12:22:00

ToList()将强制StructsTemp的evaluatation,不管它是什么,但对后续的LINQ没有影响。

... some queries on StructsFinal ....可能会或可能不会被懒评估,让我们假设它们是\它们。

Count()扩展更是不可以偷懒这样会迫使... some queries on StructsFinal ....执行,

顺便说一句,如果... some queries on StructsFinal ....结果实现ICollection<T>,如IList<T>做,那么Count()扩展将只访问的的Count财产结果。