Some LINQ methods return a query object. This object does not hold the results of the query; instead, it has all the information needed to generate those results:
var list = new List<int>() {1, 2, 3, 4, 5};
var query = list.Select(x => {
Console.Write($"{x} ");
return x;
});
The query contains a call to Console.Write
, but nothing has been output to the console. This is because the query hasn't been executed yet, and thus the function passed to Select
has never been evaluated. This is known as deferred execution -- the query's execution is delayed until some later point.
Other LINQ methods force an immediate execution of the query; these methods execute the query and generate its values:
var newList = query.ToList();
At this point, the function passed into Select
will be evaluated for each value in the original list, and the following will be output to the console:
1 2 3 4 5
Generally, LINQ methods which return a single value (such as Max
or Count
), or which return an object that actually holds the values (such as ToList
or ToDictionary
) execute immediately.
Methods which return an IEnumerable<T>
or IQueryable<T>
are returning the query object, and allow deferring the execution until a later point.
Whether a particular LINQ method forces a query to execute immediately or not, can be found at MSDN -- C#, or VB.NET.