Overall, I like working with C# and the .NET Framework. But sometimes I just can’t imagine what the designers were thinking when they put some things together. High on the list of things I don’t understand is the lack of a ForEach extension method for the generic IEnumerable interface.
IEnumerable extension methods were added in .NET 3.5 to support LINQ. These methods enable a more functional style of programming that you just couldn’t do with earlier versions of C#. For example, in earlier versions of C# (before 3.0), if you wanted to obtain the sum of items in an array of ints, you would write:
int[] a = new int[100];
// some code here to initialize the array
// now compute the sum
int sum = 0;
foreach (int x in a)
sum += x;
In .NET 3.0, the Array class implements the generic IEnumerable interface, and that interface has a Sum method to which you pass a Lambda expression. Computing the sum of items becomes a one-liner:
int sum = a.Sum(x => x);
That syntax looks pretty strange, but it takes very little getting used to and you begin to see how very powerful this functional style of programming is.
IEnumerable extension methods let you do lots of different things as one-liners. For example, if you have a list of employees and you want to select just those who are female, you can write a one-liner:
var FemaleEmployees = Employees.Where(e => e.Gender == 'F');
There are extension methods for many specific things: determining if all or any items in the collection meet a condition; applying an accumulator function over the list; computing average, minimum, maximum, sum; skipping items; taking a specific number of items, etc. But there is no extension method that will allow you to apply a function to all items in the list. That is, there is no IEnumerable.ForEach method.
I do a lot of list processing and my code is littered with calls to the IEnumerable extension methods. It’s very functional-looking code. But when I want to do something that’s not defined by one of the extension methods, I have to drop back into procedural mode. For example, I want to apply a function to all the items in the list:
foreach (var item in MyEnumerable)
{
DoSomething(item);
}
That’s crazy, when I should be able to write:
MyEnumerable.ForEach(item => DoSomething(item));
The lack of ForEach is terribly annoying. What’s worse is that ForEach does exist for arrays and for the generic List class. It’s kind of strange, though. With arrays you have to call the static Array.ForEach method:
Array.ForEach(MyArray, item => DoSomething(item));
For generic List collections, it’s an instance method:
MyList.ForEach(item => DoSomething(item));
And other collection types simply don’t have a ForEach method.
It’s simple enough to add my own ForEach extension method:
public static class Extensions
{
public static void ForEach<T>(this IEnumerable<T> source, Action<T> action)
{
foreach (var item in source)
{
action(item);
}
}
}
That’s what I did, and it works just fine. But it seems such an obvious addition (i.e. everybody would want it) that I can’t for the life of me understand why it wasn’t included in the first place.
I know the guys at Microsoft who designed this stuff aren’t stupid, so I just have to think that they had a good reason (at least in their mind) for not including a ForEach extension method for the generic IEnumerable interface. But try as I might, I can’t imagine what that reason is. If you have any idea, I’d sure like to hear it.