Reputation: 48
I was trying to better understand the function composition in linq and to that effect I wrote code like this:
var x = Enumerable.Range(1, 10);
var result = x.Select(AddFive)
.Where(FilterEvens)
.Take(1);
result.ToList();
Where the AddFive and FilterEvens methods are defined as below:
int AddFive(int n)
{
Console.WriteLine("Adding five");
return n+5;
}
bool FilterEvens(int n)
{
Console.WriteLine("Filtering evens");
return n%2 == 0;
}
If I take 1 and run it, I get the following result which is what I would expect:
Adding five
Filtering evens
If I try to take 2 or 5 however, I get:
Adding five
Filtering evens
Adding five
Filtering evens
Adding five
Filtering evens
And:
Adding five
Filtering evens
Adding five
Filtering evens
Adding five
Filtering evens
Adding five
Filtering evens
Adding five
Filtering evens
Adding five
Filtering evens
Adding five
Filtering evens
Adding five
Filtering evens
Adding five
Filtering evens
In other words it looks like the Take is going further than it needs to in the collection. Is this is a bug? (I'm guessing it's not.) If it's not, is there some good reason why it's implemented this way?
Upvotes: 1
Views: 52
Reputation: 101701
Take
is not going further. It keeps iterating until it finds as many numbers as you want.Since you have a filtering, not all numbers are returned because some of them do not satify the condition.So, you see the message for each number projected by Select
and filtered by Where.
For example in case of Take(2)
:
Select returns 6 to where - it's returned
Select returns 7 to where - not returned
Select returns 8 to where - returned
That's why you see the message three times
Upvotes: 4