LINQ, Where() vs FindAll()
FindAll()
is a function on the List<T>
type, it's not a LINQ extension method like Where
. The LINQ extension methods work on any type that implements IEnumerable
, whereas FindAll
can only be used on List<T>
instances (or instances of classes that inherit from it, of course).
Additionally, they differ in actual purpose. Where
returns an instance of IEnumerable
that is executed on-demand when the object is enumerated. FindAll
returns a new List<T>
that contains the requested elements. FindAll
is more like calling Where(...).ToList()
on an instance of IEnumerable
.
The biggest difference to me is that .FindAll is also available in .Net 2.0. I don't always have the luxury to program in .Net 3.5, so I try to remember the 'native' methods of the .Net generic collections.
It happened several times that I implemented an already available List method myself because I couldn't LINQ it.
What I find handy in this case is that, using VS2008, I can use type inference and the lambda syntax. These are compiler features, not framework features. This means I can write this and still remain within .Net 2.0:
var myOddNums = myNums.FindAll(n => n%2==1);
But if you do have LINQ available, keeping the difference between deferred execution and immediate execution is important.
If I recall correctly, the main difference (besides what they're implemented on: IEnumerable<T>
vs. List<T>
) is that Where
implements deferred execution, where it doesn't actually do the lookup until you need it -- using it in a foreach loop for example. FindAll
is an immediate execution method.
I did some tests on a list of 80K objects and found that Find()
can be up to 1000% faster than using a Where
with FirstOrDefault()
. I didn't know that until testing a timer before and after each call. Sometimes it was the same time, other times it was faster.