• Coding
  • ForEach Extension Method on Generic Types

Ok so I am tired of having to write a foreach loop everytime I want to do something to the members of the collection. I wrote the following extension method and tried to use it but I got an error:
        public static void ForEach<T>(this IEnumerable<T > list, Action<T> action)
            where T : class
        {
            foreach (T item in list)
                action(item);
        }

//this is how I'm using it:
                IList<Category> nodes = _repository.GetNodes()
                    .GetRightNodes(node).ToList()
                    .ForEach(c => (c.Left = c.Left + 2) && (c.Right = c.Right + 2));
But I'm getting this error:
Operator && cannot be applied to operands of type 'int' and 'int'
Also, using the ForEach extension method that is already available on IList causes the same error.

So what's going on?
you have the answer right there
c.Left and c.Right are of type integer, you cannot apply the && operator on them, unless you define it first, which i don't recommend, because you would be violating the common language specification, and your code will be alien to anyone other than yourself...
Hmm... I still don't quiet understand what the problem is. Basically when I'm trying to do here is add 2 to the Left and the Right of the node. How can I do that and fix my code?
&& is an operator that works on booleans, you can make it work by replacing the && by an operator that works on integers.. or better this overload of forearch
public static void ForEach<T>(this IEnumerable<T > list, params Action<T>[] action)
then you can call
.ForEach(c => c.Left +=2 , c => c.Right += 2)
That looks nice, unfortunately it doesn't work... Here's my code now:
        public static void ForEach<T>(this IEnumerable<T> list, params Action<T>[] action)
             where T : class
        {
            foreach (T item in list)
                action(item);
        }
//gives error: 'action' is a 'variable' but is used like a 'method'

//using the method as follows:
IEnumerable<Category> nodes = _repository.GetNodes()
                    .GetRightNodes(node).AsEnumerable()
                    .ForEach(c => c.Left +=2, v => v.Right += 2);
//gives an error saying: cannot convert type void to IEnumerable<Category>
Any suggestions?
Oi that make absolutely no sense.

Can't type on phone will reply when on PC.
jeez can you please look at the error messages they are pretty self descriptive :S
the variable action below is an array of actions, therefore the code should be something like this
        public static void ForEach<T>(this IEnumerable<T> list, params Action<T>[] action)
             where T : class
        {
            foreach (T item in list)
               foreach(Action<T> a in action)
                 a(item);
        }
anyway i also like to chain my calls so i would code it like this
        public static IEnumerable<T> ForEach<T>(this IEnumerable<T> list, params Action<T>[] action)
             where T : class
        {
            foreach (T item in list)
               foreach(Action<T> a in action)
                 a(item);

           return list;
        }
@xterm: i expect a rant from you, please asap
@proners: thanks a lot for the help man, the latter piece of code solved all my problems :)

I was actually thinking I should return an IEnumerable<Category> to get rid of the second error. But I had no idea how to solve the first one.

Thanks again!
I am sure Eric Meijer will be proud of your use of [wrong]LINQ[/wrong][correction]lambda's[/correction].
I hate developers.
@xterm: i expect a rant from you, please asap
I'm waiting for xterm's epic rant before I close the topic ^^
So what exactly do we gain by wrapping up the foreach language construct into an extension, pass it a fucking list of actions and execute each on it. Why?
Why not just foreach over the result of nodes and execute two statements in the loop?
Assuming we've started our lambadic masturbation and took ForEach for granted, why would you pass a list of actions when you can apply each of them in the native constructable language.

Premature Optimisation != Premeditated Performance (Execution and Developer wise) Deterioration by Needless Vague Abstraction.

I think there should be a programming police. You guys should be placed under detention.
arithma wroteSo what exactly do we gain by wrapping up the foreach language construct into an extension, pass it a fucking list of actions and execute each on it. Why?
Why not just foreach over the result of nodes and execute two statements in the loop?
Assuming we've started our lambadic masturbation and took ForEach for granted, why would you pass a list of actions when you can apply each of them in the native constructable language.

Premature Optimisation != Premeditated Performance (Execution and Developer wise) Deterioration by Needless Vague Abstraction.

I think there should be a programming police. You guys should be placed under detention.
still waiting for xterm's rant.. but i have to admit yours was quite amusing :)

now when you mentioned eric meijer, i am sure that you were ranting at me :P
but just for the record, my concern here was not the appropriate use LINQ/DSL.. but i was trying to point out how to interpret and deal with basic language constructs and compiler/runtime errors...

edit: now if i were to think of a scenario where to implement a useful foreach construct, it would be apply IO side effects(like file manipulation) so you would get an IEnumerable<IO<T>> basically an ienumerable of nothing...
@arithma: What's wrong with extension methods?
@Kassem: Herb Sutter puts it best as: When you have a hammer, everything looks like a nail.
@proners: I do try my best to amuse :)

This IO class is totally your own creation. I can't see how a side-effect based language like C# could benefit from having IE<IO<T>>. Please do indulge me.

Back to topic: Extensions were primarily made to make LINQ more expressive. Your example usage duplicates the language functionality using the language functionality without any added flexibility that I can think of. Worse yet, to use it in context, without having an abstraction to justify it (which would have been more forgivable but still wrong) is baffling. I can't invent any scenario where you saw that using extensions in this case was more useful.
At any rate, if you were to insist on using such a construct, I would advise yield returning an IEnumerable of T. (Yield return is necessary since IEnumerable could be iterating an infinite sequence..)

Kassem, just a word of advice: separate yourself into two roles. One as an architect who would develop tools for other programmers that can be used to enforce homogeneity across the project. Another as a developer on a task using those abstractions to deliver the feature. Don't mix up the situations. A developer can never succeed with an architect's mindset (abstraction, over reusability, over architecturing and perfection). Vice versa (but architects ought to express themselves most concretely in code, less so as guidelines, less so as suggestions).

Hope this helps.
This IO class is totally your own creation. I can't see how a side-effect based language like C# could benefit from having IE<IO<T>>. Please do indulge me.
I imagine IO as a container of actions.
You have your list of data, you pass it around and you add possible actions to it but you are not executing them(lazy eh :p), so there go you are accumulating to list of IO, then you may decide that you do not want to execute it all but just a part of it or execute those long running actions async, whatever.. here you go, that's what i could have thought in just 2 mins.. nighty night :P..
arithma wroteYour example usage duplicates the language functionality using the language functionality without any added flexibility that I can think of. Worse yet, to use it in context, without having an abstraction to justify it (which would have been more forgivable but still wrong) is baffling. I can't invent any scenario where you saw that using extensions in this case was more useful.
I see what you mean. You got the impression that I'm using extensions to express extensions, which is not really my intension. I just thought it "looks better" and is a better practice to chain extensions while I'm already at it (while retrieving results from a repository).
arithma wroteAt any rate, if you were to insist on using such a construct, I would advise yield returning an IEnumerable of T. (Yield return is necessary since IEnumerable could be iterating an infinite sequence..)
Example please?
arithma wroteKassem, just a word of advice: separate yourself into two roles. One as an architect who would develop tools for other programmers that can be used to enforce homogeneity across the project. Another as a developer on a task using those abstractions to deliver the feature. Don't mix up the situations. A developer can never succeed with an architect's mindset (abstraction, over reusability, over architecturing and perfection). Vice versa (but architects ought to express themselves most concretely in code, less so as guidelines, less so as suggestions).
This was actually one of the extension methods I created. Other methods include ByEmail, GetCategories, GetUsers, WithId... etc. These are basically filters which I would chain to filter the result set I'm retrieving from a repository. I basically chose to do so following the repository design pattern and the advice of some of the guys on the ASP.NET MVC team. And yes, I do admit I still haven't found the best architect for my project. I even asked for some advice here but unfortunately I got no replies.
Too much heat!

First of all let me say that I'm against using extension methods unless I'm adding something important to an existing .NET class.


Alot has been said already, I'm not going to rant about anything, I'm just going to comment on the topic at hand. There are several issues at stake here. First of all in terms of applying a ForEach extension. This could be as simple as:
public static void ForEach<T>(this IEnumerable<T> lst, Action<T> action ){
      foreach (var item in lst)
              action(item);
}
The way to use such an extension can be as simple as:
var list = Enumerable.Range(1, 100).Select(num => new Node { Left = num, Right = num });
list.ForEach(a => { a.Left += 2; a.Right += 2; });
At a first glance, this is totally correct, it compiles properly. But you will not get the desired effect if you're acting on an IEnumerable, which is the result of the first statement. The extension method on the IEnumerable will not persist the changes inside the list. you could easily test this by debugging the content of list.

What arithma said is incorrect concerning extension methods being primarily for LINQ, they are used everywhere in .NET, but totally correct concerning building an extension methods just to avoid going linear. (although back in 2006 or so i believe, using a delegate used to be more performant than a normal foreach, i'll try to dig the article by Jon Skeet later on). If you're going to build such a thing you might as well yield (ref to arithma's post) the result on every iteration, benefitting from the existing advatanges of the yield keyword (mind you yield does not perform any magic, it will throw in some code in your class and get compiled into IL).

P.S.: This could be achieved without using extensions, but i figured we're in this context...
        public static IEnumerable<T> Map<T>(this IEnumerable<T> lst, Action<T> action)
        {
            foreach (var item in lst)
            {
                action(item);
                yield return item;
            }
	}

var modified = list.Map(a => { a.Left += 2; a.Right += 2; });
Then again if you look closely at this function you'll notice that it's nothing more than a bastardization of LINQ's Select. So you can achieve the same thing through projection as well as keep the option of providing a parallel approach through TPL if you wish and method chaining.
var modified = list.Select(a => new Node { Left = a.Left + 2, Right = a.Right + 2 });
Aside from learning how to implement extension methods and iterators (yield), what is the point of creating a ForEach extension method on IEnumerable when you already have one on List<T> which you can use in your scenario?
@xterm: Jon Skeet to the rescue. In your face :P
Jon Skeet, C# in Depth 2nd Edition (Page 257, Line 7) wroteIn this chapter we’ll first look at how to use extension methods and how to write them. We’ll then examine a few of the extension methods provided by .NET 3.5, and see how they can be chained together easily. This chaining ability is an important part of the reason for introducing extension methods to the language in the first place, and is an important part of LINQ.
@MSD: You saved it by "which you can use in your scenario".
IEnumerable can signify an infinite sequence. Yielding allows you to apply transformations on the sequence. IList can't handle infinite sequences (as signified by its count property).