ForEach and RemoveAll methods of List

ForEach(Action<T>) and RemoveAll(Predicate<T>) methods of List<T> were ones of a few underused features in C# 2. In short, ForEach method allows you to apply an Action<T> delegate to every elements in a list. The result of using ForEach method is essentially the same as explicitly use foreach loop and apply the delegate to each of the item in the list. Similarly, the RemoveAll method apply bool Predicate to list items, and remove items that return true when the Predicate is applied.

At a glance, it may seem that the only benefit yielded from using ForEach and RemoveAll instead of traditional foreach loop is reducing lines of code. The more compelling scenario for using both methods will be in complex logic and nested loop. Another important use of RemoveAll is that it takes care of the Halloween problem for you as well.

Examine the code sample below, what we try to accomplish is to iterate through all customers, examine each of their order and remove that customer if one of his order has no item.

List<customer> customersToRemove = new List<customer>();
 
//customers is List
foreach(Customer customer in customers)
{
   Console.WriteLine("Customer: " + customer.Name); //print all customer name
   foreach(Order order in customer.Orders)
   {
      if(order.Items.Count < 1)
      {
         customersToRemove.Add(customer); //determine customer to remove from order
      }
   }
}
 
foreach(Customer customerToRemove in customersToRemove)
{
   customers.Remove(customerToRemove); //remove customer with invalid order
}

This code works thought it doesn’t indicate the intention of of what we try to accomplish here. We can rewrite it as

 
        customers.ForEach(               //print all customer name
            delegate(Customer customer)
            {
                Console.WriteLine("Customer: " + customer.Name);
            }
        );
        customers.RemoveAll(            //remove customers containing order with no item
            delegate(Customer customer)
            {
                foreach(Order order in customer.Orders)
                {
                    if(order.Items.Count < 1)
                        return true;
                }
            }
        )

A point to note here is that the main benefit of syntax sugar is not to reduce lines of code but make the code more readable and explicitly indicate the intent of what it’s trying to accomplish

Teera on October 13th 2008 in Software Development, .NET

Trackback URI | Comments RSS

Leave a Reply