林克在集合中做额外的传球

本文关键字:集合 林克 | 更新日期: 2023-09-27 18:28:23

我试图更好地理解linq中的函数组成,为此我写了这样的代码:

var x = Enumerable.Range(1, 10);
var result = x.Select(AddFive)
              .Where(FilterEvens)
              .Take(1);
result.ToList(); 

AddFive和FilterEvens方法定义如下:

int AddFive(int n)
{
    Console.WriteLine("Adding five");
    return n+5;
}
bool FilterEvens(int n)
{
    Console.WriteLine("Filtering evens");
    return n%2 == 0;
}

如果我取1并运行它,我会得到以下结果,这就是我所期望的:

添加五个
过滤均匀

然而,如果我试着拿2或5,我会得到:

添加五个
过滤偶数
添加五个
过滤偶数
添加五个
过滤偶数

和:

添加五个
过滤偶数
添加五个
过滤偶数
添加五个
过滤偶数
添加五个
过滤偶数
添加五个
过滤偶数
添加五个
过滤偶数
添加五个
过滤偶数
添加五个
过滤偶数
添加五个
过滤偶数

换句话说,Take似乎比它在收藏中所需要的走得更远。这是个bug吗?(我猜不是。)如果不是,有什么好的理由可以这样实现吗?

林克在集合中做额外的传球

Take不会更进一步。它不断迭代,直到找到你想要的数字。由于您有一个筛选,并不是所有的数字都会返回,因为其中一些数字不能满足条件。因此,您可以看到由Select投影并由Where. 过滤的每个数字的消息

例如,在Take(2):的情况下

Select returns 6 to where - it's returned 
Select returns 7 to where - not returned
Select returns 8 to where - returned

这就是为什么您在中看到该消息三次的原因