I'm currently reading Albahari's O'Reily book, C# in a Nutshell and am in the Linq Query chapter. He is describing the effect of delayed execution and variable capturing when making Linq querys. He gives the following example of a common mistake:
IEnumerable<char> query = "Not what you might expect";
string vowels = "aeiou";
for (int i = 0; i < vowels.Length; i++)
{
query = query.Where(c => c != vowels[i]);
}
foreach (var c in query)
{
Console.WriteLine(c);
}
Console.Read();
An IndexOutOfRangeException
is thrown once the query is enumerated but this doesn't make any sense to me. I would expect that the lambda expression in the Where operator c => c!= vowles[i]
would simply evaluate at c => c != vowels[4]
for the entire sequence, due to the effect of delayed execution and variable capturing. I went ahead and debugged to see what value i
had when the exception is thrown and found out it had the value of 5? So i went ahead and changed the condition clause, in the for loop, to i < vowels.Length-1;
and indeed no exception was thrown. Is the for loop iterating the i
at the very last iteration to 5 or is linq doing somenthing else?