假设我有这个:
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上的所有查询吗?
答案 0 :(得分:1)
如果您将List<T>
的引用分配给变量StructsTemp
,则IEnumerable<T> actually
为List<T>
并将使用{{1} }而不是枚举基础序列。
Count
因此后者将始终返回相同的值,因为它在新集合中持久存在。当底层集合发生变化时,前者可以在每次迭代时返回不同的结果(f.e。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)
为0)。
修改强>:
以下是该行为的更有意义的演示:http://ideone.com/91Yrh
答案 1 :(得分:0)
ToList()
将强制评估StructsTemp
,无论是什么,但它对随后的Linq没有影响。
... some queries on StructsFinal ....
可能会或可能不会进行延迟评估,让我们假设它们是。
Count()
扩展名不是懒惰的,因此会强制执行... some queries on StructsFinal ....
,
顺便说一句,如果... some queries on StructsFinal ....
的结果实现了ICollection<T>
,就像IList<T>
那样,那么Count()
扩展名只会访问Count
的{{1}}属性结果。