I've been reading about deferred evaluation of LINQ in the "Programming C#" book by Ian Griffiths. Deferred evaluation was explained through an example in which a Fibonacci method is defined to return a never-ending sequence.
//code 1
static IEnumerable<BigInteger> Fibonacci()
{
BigInteger n1 = 1;
BigInteger n2 = 1;
yield return n1;
while (true)
{
yield return n2;
BigInteger t = n1 + n2;
n1 = n2;
n2 = t;
}
}
Then in Main method only the even numbers of this sequence are retrieved using LINQ:
//code 2
static void Main(string[] args)
{
var evenFib = from n in Fibonacci()
where n % 2 == 0
select n;
foreach (BigInteger n in evenFib)
{
Console.WriteLine(n);
Console.ReadKey();
}
}
Next it was explained that due to the deferred evaluation feature of LINQ available by LINQ to Object provider in System.Linq, there would be no problem in printing out the numbers since the numbers are processed in the LINQ only when demanded. However, it compared it to another example in the same chapter in which an extension method of where was defined:
//code 3
public static class CustomLinqProvider
{
public static CultureInfo[] Where(this CultureInfo[] cultures,
Predicate<CultureInfo> filter)
{
return Array.FindAll(cultures, filter);
}
}
It stated that if the where method was implemented like this it would only print out a single number cause the where method would never finish its job. So my question is how can I define an extension method of where like the one in code 3 for the Fibonacci example and why would it print out a single number when the where method would never return?
Here is the exact paragraph of the book having the problem I'm referring to, so please check out this one too because I might have misunderstood it (this paragraph explains the Fibonacci example, i.e. code 1 and code 2 by the way):
This will use the Where extension method that LINQ to Objects provides for IEnumerable. If that worked the same way as my CustomLinqProvider class’s Where method for CultureInfo[], this program would never make it as far as printing out a single number. My Where method did not return until it had filtered the whole of its input and produced a fully populated array as its output. If the LINQ to Objects Where method tried that with my infinite Fibonacci enumerator, it would never finish.