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.