Linq 对延期执行的质疑

Linq 对延期执行的质疑,linq,deferred-execution,Linq,Deferred Execution,假设我有这个: IEnumerable<MyObject> StructsTemp; 如果以后我这样做呢 StructsTemp.Count() 它会在StructsTemp上重新执行n个查询吗?这将重新执行StructsTemp.ToList()?这会重新执行StructsFinal上的所有查询吗 如果将List的引用指定给变量StructsTemp,则IEnumerable实际上是List的一个List,并将使用它的Count属性,而不是枚举底层序列 var numbers

假设我有这个:

IEnumerable<MyObject> StructsTemp;
如果以后我这样做呢

StructsTemp.Count()

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

如果将
List
的引用指定给变量
StructsTemp
,则
IEnumerable实际上是
List
的一个
List
,并将使用它的
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();
var number=new[]{1,2,3};
IEnumerableevenNumbers=numbers,其中(i=>i%2==0);
//延迟,将枚举序列以计数偶数
int count=evenNumbers.count();
evenNumbers=evenNumbers.ToList();
//不延迟,使用List的Count属性
count=偶数。count();
因此,后者将始终返回相同的值,因为它在新集合中保持不变。当基础集合发生更改时,前者可以在每次迭代中返回不同的结果(例如,f.e.
numbers.Remove(2)
导致
evenNumbers.Count
为0)

编辑

下面是该行为的一个更有意义的演示:

ToList()
将强制计算
StructsTemp
,不管是什么,但它对后续Linq没有影响

。。。StructsFinal….
上的某些查询可能是惰性计算的,也可能不是惰性计算的,假设是惰性计算的

Count()。。。对StructsFinal….的一些查询


另外,如果
的结果。。。对StructsFinal…
的一些查询实现了
ICollection
,如
IList
执行,那么
Count()
扩展将只访问结果的
Count
属性。

因此evenNumbers=evenNumbers.ToList();将IEnumerable“变成”列表吗O我不这么认为…@markzzz:
IList
实现了
IEnumerable
,因此每个列表也隐式地是一个IEnumerable。那只是继承。但是引用从具有基础集合的linq查询更改为不同的
列表
。这一点并不清楚:)假设,在
int count=evenNumbers.count()之前我用foreach“循环”偶数:那是什么?不是一个列表:OAlso:如果我没有evenNumbers=evenNumbers.ToList(),每一个数字。Count();是否每次都执行查询(where)?@markzzz:如果需要,可以使用
evernumbers.Count
属性。您只需相应地强制转换它,这就是
Enumerable.Count()
在枚举序列之前首先尝试的内容:
((ICollection)evenNumber).Count
。但正如我已经提到的,这并不是必需的,因为
Enumerable.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();