2014-10-30 148 views
1

我是想更好地了解LINQ的功能组成,该效果做额外的传球,我写这样的代码:的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然而,我得到:

新增五个
过滤找齐
新增五个
过滤找齐
新增五
Filtering evens

和:

新增五个
过滤找齐
新增五个
过滤找齐
新增五个
过滤找齐
新增五个
过滤找齐
新增五个
过滤找齐
添加五个
过滤找齐
新增五个
过滤找齐
新增五个
过滤找齐
新增五个
过滤找齐

换句话说,它看起来像采取进一步去比它需要在集合。这是一个错误吗? (我猜这不是)。如果不是这样,那么为什么以这种方式实现它有一些很好的理由吗?

+1

它只是预期。试着在'.Range(2,10)'上拍'(1)',你会看到两个项目被投影和过滤。:)在所有先前的转换之后,'Take'将会像从序列*中指定的一样多的项目*。 – 2014-10-30 15:03:26

回答

4

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 

这就是为什么你看到消息三次

+0

哦,当然!谢谢! – aj100 2014-10-30 15:15:21