LINQ methods executing sequence

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 Iterators 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:

enter image description here enter image description here

Second statement:

enter image description here enter image description here

Could you explain me why?

Jon Skeet
people
quotationmark

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.

people

See more on this question at Stackoverflow