This post was migrated from Justin’s personal blog, 'Codethinked.com.' Views, opinions, and colorful expressions should be taken in context, and do not necessarily represent those of Simple Thread (and were written under the influence of dangerous levels of caffeination).

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.

8 Comments

Andy

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

Reply
Bryan Watts

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.

Reply
Alexander

I would not make it a void method, but an IEnumerable<T> method, like other linq queries.

Reply
Justin Etheredge

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.

Reply
Jonathan Pryor

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).

Reply

Leave a Reply

Your email address will not be published. Required fields are marked *