How to tell if an IEnumerable is subject to deferred execution?

Deferred execution of LINQ has trapped a lot of people, you’re not alone.

The approach I’ve taken to avoiding this problem is as follows:

Parameters to methods – use IEnumerable<T> unless there’s a need for a more specific interface.

Local variables – usually at the point where I create the LINQ, so I’ll know whether lazy evaluation is possible.

Class members – never use IEnumerable<T>, always use List<T>. And always make them private.

Properties – use IEnumerable<T>, and convert for storage in the setter.

public IEnumerable<Person> People 
{
    get { return people; }
    set { people = value.ToList(); }
}
private List<People> people;

While there are theoretical cases where this approach wouldn’t work, I’ve not run into one yet, and I’ve been enthusiasticly using the LINQ extension methods since late Beta.

BTW: I’m curious why you use ToArray(); instead of ToList(); – to me, lists have a much nicer API, and there’s (almost) no performance cost.

Update: A couple of commenters have rightly pointed out that arrays have a theoretical performance advantage, so I’ve amended my statement above to “… there’s (almost) no performance cost.”

Update 2: I wrote some code to do some micro-benchmarking of the difference in performance between Arrays and Lists. On my laptop, and in my specific benchmark, the difference is around 5ns (that’s nanoseconds) per access. I guess there are cases where saving 5ns per loop would be worthwhile … but I’ve never come across one. I had to hike my test up to 100 million iterations before the runtime became long enough to accurately measure.

Leave a Comment