Linq - What is the quickest way to find out deferred execution or not?
The guidelines I use:
Always assume any API that returns
IEnumerable<T>
orIQueryable<T>
can and probably will use deferred execution. If you're consuming such an API, and need to iterate through the results more than once (e.g. to get a Count), then convert to a collection before doing so (usually by calling the .ToList() extension method.If you're exposing an enumeration, always expose it as a collection (
ICollection<T>
orIList<T>
) if that is what your clients will normally use. For example, a data access layer will often return a collection of domain objects. Only exposeIEnumerable<T>
if deferred execution is a reasonable option for the API you're exposing.
Generally methods that return a sequence use deferred execution:
IEnumerable<X> ---> Select ---> IEnumerable<Y>
and methods that return a single object doesn't:
IEnumerable<X> ---> First ---> Y
So, methods like Where
, Select
, Take
, Skip
, GroupBy
and OrderBy
use deferred execution because they can, while methods like First
, Single
, ToList
and ToArray
don't because they can't.
There are also two types of deferred execution. For example the Select
method will only get one item at a time when it's asked to produce an item, while the OrderBy
method will have to consume the entire source when asked to return the first item. So, if you chain an OrderBy
after a Select
, the execution will be deferred until you get the first item, but then the OrderBy
will ask the Select
for all the items.