I am reading a book about C# in advanced level. And, now I am reading this part:
Behind-the-scenes operation of the Linq query methods that implement delegate-based syntax.
So far, I have read about Where
, Select
, Skip
, SkipWhile
, Take
, TakeWhile
methods.
And, I know about Defferred and Immediate execution and Iterator
s which is returned by some of these methods.
Deferred execution is a pattern of the execution model by which the CLR ensures a value will be extracted only when it is required from the IEnumerable-based information source. When any Linq operator uses the deferred execution, the CLR encapsulates the related information, such as the original sequence, predicate, or selector (if any), into an iterator, which will be used when the information is extracted from the original sequence using ToListmethod or ForEachmethod or manually using the underlying GetEnumeratorand MoveNextmethods in C#.
Now let's take these two examples:
IList<int> series = new List<int>() { 1, 2, 3, 4, 5, 6, 7 };
// First example
series.Where(x => x > 0).TakeWhile(x => x > 0).ToList();
// Second example
series.Where(x => x > 0).Take(4).ToList();
When I am putting breakpoints and debugging these two statements, I can see one difference.
TakeWhile()
method executing when an item is met the condition in Where
statement. But, this is not the case with Take
method.
First statement:
Second statement:
Could you explain me why?
It's not entirely clear what you mean, but if you're asking why you hit a breakpoint in the lambda expression in TakeWhile
, but you don't hit one within Take
, it's just that Take
doesn't accept a delegate at all - it just accepts a number. There's no user-defined code to execute while it's finding a value to return, so there's no breakpoint to hit.
In your example with TakeWhile
, you've got two lambda expressions - one for Where
and one for TakeWhile
. So you can break into either of those lambda expressions.
It's important to understand that the Where
and TakeWhile
methods themselves are only called once - but the sequences they return evaluate the delegate passed to them for each value they encounter.
You might want to look at my Edulinq blog series for more details about the innards of LINQ.
See more on this question at Stackoverflow