0

假设我有这个:

IEnumerable<MyObject> StructsTemp;

我在 StructsTemp 上编写了 n 个查询,以便它从数据库中填充,依此类推。后来,我执行它们调用.ToList()

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

如果以后我这样做呢?

StructsTemp.Count()

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

4

2 回答 2

1

如果您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();

所以后者总是会返回相同的值,因为它被持久化在一个新的集合中。当底层集合发生变化时,前者可以在每次迭代中返回不同的结果(fenumbers.Remove(2)导致evenNumbers.Count为 0)。

编辑

这是该行为的更有意义的演示:http: //ideone.com/91Yrh

于 2012-07-20T11:13:51.580 回答
0

ToList()将强制评估StructsTemp,无论是什么,但它对后续的 Linq 没有影响。

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

Count()扩展不是懒惰的,所以会强制执行... some queries on StructsFinal ....,

... some queries on StructsFinal ....顺便说一句,如果implements的结果是ICollection<T>一样IList<T>的,那么Count()扩展将只访问Count结果的属性。

于 2012-07-20T11:17:00.740 回答