怀疑
问题描述:
假设我有这样的:怀疑
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
答
ToList()
将强制StructsTemp
的evaluatation,不管它是什么,但对后续的LINQ没有影响。
... some queries on StructsFinal ....
可能会或可能不会被懒评估,让我们假设它们是\它们。
的Count()
扩展更是不可以偷懒这样会迫使... some queries on StructsFinal ....
执行,
顺便说一句,如果... some queries on StructsFinal ....
结果实现ICollection<T>
,如IList<T>
做,那么Count()
扩展将只访问的的Count
财产结果。
so evenNumbers = evenNumbers.ToList();将“变成”一个IEnumerable到列表? :O我不这么认为... – markzzz 2012-07-20 12:11:21
@markzzz:'IList'实现'IEnumerable '因此每个列表也是隐式的可枚举。这只是继承。但是,引用从具有基础集合的linq查询更改为不同的'List '。 –
2012-07-20 12:17:50
这是不明确的:)假设,在int count = evenNumbers.Count();'I“之前循环”evenNumbers与foreach:那是什么?不是列表:O –
markzzz
2012-07-20 12:22:00