List<T> has a method called ForEach that takes an Action<T> delegate, and I wanted one for IEnumerable. I also had someone ask about it in my previous post. It wasn’t hard to write, but I figured I would throw it up here for future reference and also in case anyone needed help getting theirs working. If anyone notices anything I did that was dumb you can give me feedback as well. I believe I actually implemented something similar to this a while back, but anyways… without further ado…
public static void ForEach<T>(this IEnumerable<T> enumerable, Action<T> action)
{
if (enumerable == null)
throw new ArgumentNullException("enumerable");
if (action == null)
throw new ArgumentNullException("action");
foreach (T item in enumerable)
{
action(item);
}
}
Hope it helps.
Loved the article? Hated it? Didn’t even read it?
We’d love to hear from you.
Justin, pretty much what I had in my version. You might add the following which comes from the code on a List<> ForEach:
if (func == null)
throw new ArgumentNullException("func");
-Andy
Nice. I assumed that method was an extension method like the rest – nope, I was just using List<T>.
You should throw an ArgumentNullException for each parameter when appropriate. Also, naming your action "func" is confusing because Action and Func serve mutually exclusive purposes.
@Andy and @Bryan Good points, both of you. I will make updates.
I would not make it a void method, but an IEnumerable<T> method, like other linq queries.
I don’t follow. If the ForEach method just returned IEnumerable<T>, then you would still have to iterate over it to do an action. I could do a Map method, like I did in this post … http://www.codethinked.com/post/2007/11/Lambdas-and-Closures-and-Currying-Oh-my!-(Part-4).aspx Look at the one toward the end of that post, but that is a bit of a different operation from what I am trying to achieve here. The Map statement is essentially the same as the LINQ Select extension method.
Simple, yet awesome at the same time.
Thanks!
Kevin Pilch Bisson of Microsoft (http://blogs.msdn.com/kevinpilchbisson/) and I discussed this on ##csharp on freenode.net earlier, and came up with the following set of methods:
public static IEnumerable<T> Apply<T> (this IEnumerable<T> self, Action<T> action)
{
foreach (T t in self) {
action (t);
yield return t;
}
}
public static void Apply<T> (this IEnumerable<T> self)
{
#pragma warning disable 219
foreach (T t in self) {
// ignore t
}
#pragma warning restore 219
}
The idea is that Apply<T>(IEnumerable<T>, Action<T>) can be chained, as it returns an IEnumerable<T>, but Apply<T>(IEnumerable<T>) causes an immediate application of the list, thus forcing computation and invoking all delegates.
I’ll be working on getting this into Mono.Rocks (http://www.mono-project.com/Rocks).
Very cool stuff. I’ll definitely have to check out Mono.Rocks.