Lazy evaluation[^]: the value of an expression is not evaluated until it is needed. Eager evaluation[^]: the value of an expression is evaluated as soon as it gets bound to a variable.
var arr = new[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
var elementsGreaterThan5Lazy = from n in arr
where n > 5
select n; // the query doesn't execute here. If you have a million elements in the array you're not filtering them at this point of the program.
var elementsGreaterThan5Eager = (from n in arr
where n > 5
select n).ToArray(); // the query does execute here because you're forcing the execution by creating an array of the results (you want those values > 5 now in an array).
The first expression actually evaluates to an iterator (an object that is to perform the desired operation) not the actual result of the operation (the elements which are greater than 5). In the second expression, the ToArray method is forcing the execution of the query to get the elements as an array. In other words, you want an actual array now so the query has to be executed to get the array. Let's say you then write something like
var firstElementGreaterThan5 = elementsGreaterThan5Lazy.First();
Here you're forcing the query to execute to get the first element that is greater than 5 (and to throw an exception when the sequence is empty). Actually, you're not looping over all the elements, you're just looping until you find the desired value. In other words, if you have a million elements in the array and the first element greater than 5 is in the second location, you're actually doing 2 iterations and not iterating over the whole million elements. Some extension methods like ToArray, ToList, First, Last... do force the execution of the query. While other methods like Where, Take, Skip... do not execute the query but return an iterator. You can tell whether a method forces the execution or not from its name or from the documentation. I hope that answers your question.
Eslam Afifi