views:

120

answers:

3

I'd like to write:

IEnumerable<Car> cars;
cars.Find(car => car.Color == "Blue")

Can I accomplish this with extension methods? The following fails because it recursively calls itself rather than calling IList.Find().

public static T Find<T>(this IEnumerable<T> list, Predicate<PermitSummary> match)
{
    return list.ToList().Find(match);
}

Thanks!

+15  A: 

This method already exists. It's called FirstOrDefault

cars.FirstOrDefault(car => car.Color == "Blue");

If you were to implement it yourself it would look a bit like this

public static T Find<T>(this IEnumerable<T> enumerable, Func<T,bool> predicate) {
  foreach ( var current in enumerable ) {
    if ( predicate(current) ) {
      return current;
    }
  }
  return default(T);
}
JaredPar
Thanks. Didn't realize this overload existed.
Brian
Great Answer! I never realized this overload existed and have been adding superfluous .Where(...).First() statements.
JHappoldt
A: 

You know that Find(...) can be replaced by Where / First

IEnumerable<Car> cars;
var result = cars.Where(c => c.Color == "Blue").FirstOrDefault();

This'll return null in the event that the predicate doesn't match.

Aren
No need for the Where. FirstOrDefault will take the Predicate too.
Stephan
You can specify the predicate directly on `FirstOrDefault()` and leave `Where()` out.
Daniel Brückner
Ah, you are right, forgot about the predicate.
Aren
+1  A: 

Jared is correct if you are looking for a single blue car, any blue car will suffice. Is that what you're looking for, or are you looking for a list of blue cars?

First blue car:

Car oneCar = cars.FirstOrDefault(c => c.Color.Equals("Blue));

List of blue cars:

IEnumerable<Car> manyCars = cars.FindAll(car => car.Color.Equals("Blue"));
StyxRiver
Thanks, and if you are looking for exactly one blue car:cars.Single(car => car.Color.Equals("Blue")
Brian
Single is okay if you are guaranteed to have ONLY ONE car in the entire list. If you have more than one car, or no cars at all, you're going to throw an InvalidOperationException. FirstOrDefault will return your blue car, or the default type (often null). First will throw an exception if there is nothing that matches the predicate.
StyxRiver