Freigeben über


foreach keyword or ForEach extension method?

Is this a question of taste, or something more serious? [Warning: this post won’t change your life J]

I found myself writing the following extension method yet again the other day;

public static void ForEach<T>(

    this IEnumerable<T> source,

    Action<T> action)

{

    foreach (T item in source)

    {

        action(item);

    }

}

This means I can write simple (contrived) code like the following;

entities.ForEach<ObjectDefinition>(o => o.DeleteDbRecord());

This will enumerate all my ObjectDefinition objects and call DeleteDbRecord on each. But why didn’t I just write it like this?

foreach (ObjectDefinition o in entities)

{

    o.DeleteDbRecord();

}

I’ve raised this because some code I’ve seen (and written!) has reached a saturation point, where lambdas, extension methods, and other concepts have taken over - meaning the code looks more like it was written in LISP than C#.

But does that matter?

A quick search shows there are all sorts of discussions about this online, which is interesting. It is actually quite an old discussion now!

Comments

  • Anonymous
    April 27, 2009
    From a performance standpoint it matters.  Lambdas are essentially delegates and do not perform as well as a normal loop structure.  Test it. At best you're only saving a few keystrokes, maybe none depending on what intellisense does for you between the two versions. This is trying to solve a problem that doesn't exist.   I will admit that I sometimes take the slight performance hit and Linq/Lambdas when it makes the code more readable. But in critical loops and where the Linq code may actually read more complex, I will use a normal loop construct.

  • Anonymous
    April 27, 2009
    PingBack from http://asp-net-hosting.simplynetdev.com/foreach-keyword-or-foreach-extension-method/

  • Anonymous
    April 27, 2009
    The comment has been removed

  • Anonymous
    April 27, 2009
    I'm lucky I guess that most of my perf can be found with better algorithms. I can only recall a few times where the overhead of delegate invocation was an issue, and once of those was a bug in the CLR. foreach has overhead too, versus a for loop and manual indexing. Maybe the compiler optimizes it on some types, but I don't believe it does on any IList. In F#, I write much less efficient code, and it's very rarely a problem. If I do profile and find a certain path is slow, fine, move back to mutables and even pointers if necesary. But I highly doubt that many people work in application where these sort of optimizations are needed all the time...

  • Anonymous
    April 27, 2009
    @ Michael; Ditto - every now and then some code needs low level tuning, but I prioritise maintainability first by default... generally it is architectural decisions that impact perf more in the fields I do most work in. But what's interesting is that you use F# - so you're used to the functional paradigm... as am I from quite some time ago, but others may not be. I wonder if this makes you (and I) more accepting of lambdas etc as programming constructs as it is just a natural fit? Simon

  • Anonymous
    April 27, 2009
    F# introduced me to the functional mindset, but before I could use F#, I had a couple of years of full time C# (and still have a lot of C# still). The fact C# came out with a nice intro FP feature set with 3.0 was a sanity-saving bonus :). Personal experience tells me as soon as a C# programmer "gets it" -- they grasp they can toss around functions -- they tend to love it and use it tons. Anyone who likes LINQ is pretty much validating that, don't you think?