The paragraph you showed from the book doesn't say it will print a single number. It says it will never print a single number.

[...] this program would never make it as far as printing out a single number [...]

Indeed, deferred execution would allow you to run through an infinite sequence, while exeucting the full sequence without deferred exeuction would never end.


how can I define an extension method of where like the one in code 3 for the Fibonacci example

You can use yield return again if you want deferred execution.

public static IEnumerable<CultureInfo> MyWhere(this IEnumerable<CultureInfo> source, Predicate<CultureInfo> filter) {
    foreach (var thing in source) {
        if (filter(thing)) yield return thing;

Note that it has to return and accept IEnumerable<CultureInfo>s because arrays can't be "infinite", IEnumerable<T>s can, because they can use deferred execution.

why would it print out a single number when the where method would never return?

If you try to call your CustomLinqProvider.Where method with an infinite IEnumerable<CultureInfo>, you'd first have to convert that to a CultureInfo[], which you will do by using ToArray. Since the IEnumerable<T> is infinite, ToArray will go on forever. It's not that Where will not return, it's that ToArray will not.

Also, the book says

this program would never make it as far as printing out a single number

"would never make it as far as" means "wouldn't even".


I defined an extension method as the following and it didn't print out anything. The point is that when it's going to be treated like an array then the where method would never return, hence the evaluation of evenFib would never end and we'll have nothing printed. I also made sure in my code when both LINQ to Object provider and my own extension method are available, my extension method would be used. I didn't change code 1 and code 2 by the way.

public static T[] Where<T>(this IEnumerable<T> src,
        Predicate<T> filter)
            var array = src.ToArray();           
            return Array.FindAll(array,filter);

Related Query

More Query from same tag