Wednesday, March 25, 2009

Missing IEnumerable<T>.ForEach(Action<T> action)

Have you ever wanted to code something like this in .NET 3.5:
var repository = new CustomerRepository();
repository.Customers.ForEach(customer => Console.WriteLine(string.Format("Customer: {0} {1}",
customer.FirstName, customer.LastName)));
Console.Read();
Where Customers is of type Collection. Well you can't out of the box as the framework doesn't provide an extension for IEnumerable foreach (which is what Collection implements).

The Repository and domain object in the above case looks like this:
public class CustomerRepository
{
public CustomerRepository()
{
Customers = new Collection<Customer>()
{
new Customer()
{
FirstName = "Simon",
LastName = "Hart"
},
new Customer()
{
FirstName = "Joe",
LastName = "Bloggs"
}
};
}

public ICollection<Customer> Customers
{
get; set;
}
}

public class Customer
{
public string FirstName
{
get; set;
}

public string LastName
{
get; set;
}
}
You can make the above call work with this simple extension for IEnumerable:
public static class GenericIEnumerableExtensions
{
public static void ForEach<T>(this IEnumerable<T> collection, Action<T> action)
{
foreach (var item in collection)
{
action(item);
}
}
}
It's quite simple in that it accepts one parameter, an Action delegate with one parameter - this could be extended to do whatever you want. Although the above is in line with the List.ForEach extension method.

The benefit of this is it simply reads better with less code.

You might find this library found on codeplex useful: http://extensionmethodsyay.codeplex.com/

2 comments:

Daniel Marbach said...

Hello Simon,
You might want to look at the ashmind extensions. They are very useful too but unfortunately not documented...

http://code.google.com/u/ashmind/

Simon Hart said...

Thanks Daniel, I'll check it out.

--
Simon.