gpt4 book ai didi

c# - 为什么从 LINQ Where() 方法返回的 IEnumerable 不完全由 Count() 使用?

转载 作者:太空宇宙 更新时间:2023-11-03 21:58:20 25 4
gpt4 key购买 nike

我知道 Count() LINQ 提供的方法进行了优化,它会检查源序列是否实现了 ICollection<T>如果是这样,请调用 Count属性而不是遍历整个集合。使用此优化时,基础 IEnumerable<T>未被消耗,因此它可以被后续的其他调用消耗 Count() .

值得注意的是,接受谓词的 Count 重载不会执行此类优化,因为它必须检查每个元素的值。

现在考虑下面的完整程序:

using System;
using System.Collections.Generic;
using System.Linq;

namespace count_where_issue
{
class Program
{
static void Main(string[] args)
{
IEnumerable<int> items = new List<int> {1, 2, 3, 4, 5, 6};
IEnumerable<int> evens = items.Where(y => y % 2 == 0);
int count = evens.Count();
int first = evens.First();
Console.WriteLine("count = {0}", count);
Console.WriteLine("first = {0}", first);
}
}
}

打印,

count = 3
first = 2

我的预期是伯爵需要消耗整个 evens Where() 返回的序列以及随后对 evens.First() 的调用会失败 InvalidOperationException因为该序列不包含任何元素。

为什么这个程序会这样工作?我通常不会尝试使用 IEnumerable<T>在调用 `Count() 之后。依赖这种行为是否不明智?

最佳答案

我不知道这是不是你的意思,但是 evens.Count()evens.First() 都枚举了 items.Where (...)

您可以在以下输出中看到这一点:

class Program
{
static void Main(string[] args)
{
IEnumerable<int> items = new List<int> { 1, 2, 3, 4, 5, 6 };
IEnumerable<int> evens = items.Where(y => isEven(y));

int count = evens.Count();
Console.WriteLine("count = {0}", count);

int first = evens.First();
Console.WriteLine("first = {0}", first);

}

private static bool isEven(int y)
{
Console.Write(y + ": ");

bool result = y % 2 == 0;

Console.WriteLine(result);
return result;
}
}

这是:

1: False
2: True
3: False
4: True
5: False
6: True
count = 3
1: False
2: True
first = 2

关于c# - 为什么从 LINQ Where() 方法返回的 IEnumerable 不完全由 Count() 使用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11276328/

25 4 0