Why is .ForEach() on IList<T> and not on IEnumerable<T>?
According to Eric Lippert, this is mostly for philosophical reasons. You should read the whole post, but here's the gist as far as I'm concerned:
I am philosophically opposed to providing such a method, for two reasons.
The first reason is that doing so violates the functional programming principles that all the other sequence operators are based upon. Clearly the sole purpose of a call to this method is to cause side effects.
The purpose of an expression is to compute a value, not to cause a side effect. The purpose of a statement is to cause a side effect. The call site of this thing would look an awful lot like an expression (though, admittedly, since the method is void-returning, the expression could only be used in a “statement expression” context.)
It does not sit well with me to make the one and only sequence operator that is only useful for its side effects.
The second reason is that doing so adds zero new representational power to the language.
Because ForEach(Action)
existed before IEnumerable<T>
existed.
Since it was not added with the other extension methods, one can assume that the C# designers felt it was a bad design and prefer the foreach
construct.
Edit:
If you want you can create your own extension method, it won't override the one for a List<T>
but it will work for any other class which implements IEnumerable<T>
.
public static class IEnumerableExtensions
{
public static void ForEach<T>(this IEnumerable<T> source, Action<T> action)
{
foreach (T item in source)
action(item);
}
}
Because ForEach()
on an IEnumerable is just a normal for each loop like this:
for each T item in MyEnumerable
{
// Action<T> goes here
}