Just trying to understand this better. I know this is because of Deffered Execution
But what is it causing the method not getting called immediately. This is from EduLinq from JonSkeet.
public static partial class Enumerable
{
public static IEnumerable<TSource> Where<TSource>(
this IEnumerable<TSource> source,
Func<TSource, bool> predicate)
{
if (source == null)
{
throw new ArgumentNullException("source");
}
if (predicate == null)
{
throw new ArgumentNullException("predicate");
}
foreach (TSource item in source)
{
if (predicate(item))
{
yield return item;
}
}
}
}
This is where I am using it.
List<int> list = new List<int>() { 1, 3, 4, 2, 8, 1 };
var s = list.Where(x => x > 4);
var result = s.ToList();
My question is though Where is a static method on IEnumerable why is it not called on list.where(). But it is called on s.ToList().
I have a breakpoint on Enumerable.Where() it is not hit on s = list.Where(x => x > 4) but the breakpoint is hit on s.ToList()
After I saw the comment from YUCK Why does LINQ have deferred execution? I am adding this to the question.
Please let me know.
The
Wheremethod is actually called, but it returns anIEnumerable<T>. This return value is actually a class the compiler implements for you.Note that your implementation uses an iterator (it includes yield return …). When this occurs, the compiler changes your method around so that it creates a compiler-generated class, and, as you actually iterate through the
IEnumerable<T>, the code you wrote gets executed.The first time
MoveNextis called, the code up to your firstyield returnwill get executed. The second call will go until the next, etc.Calling
ToList()enumerates through the entireIEnumerable<T>, which in turn executes your entire method.Also –
ToList()isn’t required here to have your code execute. You could use a foreach loop:Or even execute the calls manually: