List<object>.RemoveAll - How to create an appropriate Predicate

The RemoveAll() methods accept a Predicate<T> delegate (until here nothing new). A predicate points to a method that simply returns true or false. Of course, the RemoveAll will remove from the collection all the T instances that return True with the predicate applied.

C# 3.0 lets the developer use several methods to pass a predicate to the RemoveAll method (and not only this one…). You can use:

Lambda expressions

vehicles.RemoveAll(vehicle => vehicle.EnquiryID == 123);

Anonymous methods

vehicles.RemoveAll(delegate(Vehicle v) {
  return v.EnquiryID == 123;
});

Normal methods

vehicles.RemoveAll(VehicleCustomPredicate);
private static bool
VehicleCustomPredicate (Vehicle v) {
    return v.EnquiryID == 123; 
}

A predicate in T is a delegate that takes in a T and returns a bool. List<T>.RemoveAll will remove all elements in a list where calling the predicate returns true. The easiest way to supply a simple predicate is usually a lambda expression, but you can also use anonymous methods or actual methods.

{
    List<Vehicle> vehicles;
    // Using a lambda
    vehicles.RemoveAll(vehicle => vehicle.EnquiryID == 123);
    // Using an equivalent anonymous method
    vehicles.RemoveAll(delegate(Vehicle vehicle)
    {
        return vehicle.EnquiryID == 123;
    });
    // Using an equivalent actual method
    vehicles.RemoveAll(VehiclePredicate);
}

private static bool VehiclePredicate(Vehicle vehicle)
{
    return vehicle.EnquiryID == 123;
}

This should work (where enquiryId is the id you need to match against):

vehicles.RemoveAll(vehicle => vehicle.EnquiryID == enquiryId);

What this does is passes each vehicle in the list into the lambda predicate, evaluating the predicate. If the predicate returns true (ie. vehicle.EnquiryID == enquiryId), then the current vehicle will be removed from the list.

If you know the types of the objects in your collections, then using the generic collections is a better approach. It avoids casting when retrieving objects from the collections, but can also avoid boxing if the items in the collection are value types (which can cause performance issues).