Reputation: 33653
From what I can see, the ForEach
method is available only for the List
class.
Why is that? I can see no reason for ForEach
not to be available to any class implementing the IEnumerable
/IEnumerator
interfaces, and this is a really useful method if you need to perform a small action (1 line is more readable than 1 line + 2 boilerplate foreach syntax...).
Update: I'll clarify my question. There are perfectly valid reasons for including ForEach
in sequences. There are perfectly good reasons for not including ForEach
in all sequences.
But I cannot understand why would ForEach
be included in just some of the sequences.
Upvotes: 10
Views: 861
Reputation: 96557
See Eric Lippert's post: "foreach" vs "ForEach"
A number of people have asked me why there is no Microsoft-provided “ForEach” sequence operator extension method. The List class has such a method already of course, but there’s no reason why such a method could not be created as an extension method for all sequences.
...
But we can go a bit deeper here. 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 second reason is that doing so adds zero new representational power to the language.
...
Well, the VS Languages team does not have any influence on what goes into List. I personally find the "ForEach" method on List philosophically troubling for all the same reasons that I would find an extension method on IEnumerable troubling. (And the VSL team does control that.) The one mitigating factor is that List is clearly designed to be a mutable, not-side-effect-free data structure, so using expressions that mutate it seems slightly less bad. -- Eric
Upvotes: 24
Reputation: 22443
Here is a different version of the .ForEach() extension method that supports exception handling. This will catch all exeptions so you may want to rethrow those you don't handle.
(This was written for use with VS 2010... if you are using previous version you will probably need to remove the = null from the method signature)
public static void SafeForEach<T>(this IEnumerable<T> input,
Action<T> action,
Action<T, Exception> faultAction = null)
{
if (input == null || action == null)
return;
foreach (var item in input)
try
{
action(item);
}
catch (Exception ex)
{
if (faultAction == null)
Debug.WriteLine(ex);
else
faultAction(item, ex);
}
}
Upvotes: 0
Reputation: 17445
Technically, with .NET 3.5, you could do this: (you need to include System.Linq)
IEnumerable<string> a = ...
a.All(i => { DoSomethingWith(i); return true; });
Upvotes: 3
Reputation: 1790
Correct. However, if you want to use the advantage of ForEach loop, there's a method called "ToList" as shown below used to convert an array back to List.
String[] array = new String[3];
List<String> list = array.ToList<String>();
Upvotes: 2
Reputation: 8237
You are right, the method is defined in the List class. However, its pretty easy to create a extension method that does the same thing.
public static void ForEach<T>(this IEnumerable<T> enumerable, Action<T> action)
{
foreach (var t in enumerable)
action(t);
}
Upvotes: 7