codethinked (kōdthĭngked) adj. To be consumed by or obsessed with code.

IEnumerable ForEach extension method

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.

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

Andy

May 8. 2008 20:28

United States
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.

Bryan Watts

May 8. 2008 20:28

United States
Justin Etheredge

@Andy and @Bryan Good points, both of you. I will make updates.

Justin Etheredge

May 8. 2008 20:33

United States
Alexander

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

Alexander

May 8. 2008 21:17

Netherlands
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 ... www.codethinked.com/.../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.

Justin Etheredge

May 9. 2008 02:04

United States
pingback

Pingback from alvinashcraft.com

Dew Drop - May 9, 2008 | Alvin Ashcraft's Morning Dew

alvinashcraft.com

May 9. 2008 11:48

Will Asrari

Simple, yet awesome at the same time.

Thanks!

Will Asrari

June 6. 2008 00:24

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

Jonathan Pryor

June 6. 2008 01:36

United States
Justin Etheredge

Very cool stuff. I'll definitely have to check out Mono.Rocks.

Justin Etheredge

June 6. 2008 02:44

United States
pingback

Pingback from blogs.msdn.com

Kirill Osenkov : ForEach

blogs.msdn.com

January 31. 2009 23:41

Add Comment


(Will show your Gravatar icon)

  Country flag

biuquote
  • Comment
  • Preview
Loading