Click here to Skip to main content
13,404,383 members (44,977 online)
Click here to Skip to main content
Add your own
alternative version


23 bookmarked
Posted 13 Jun 2010

List(T).ForEach or Foreach, It Doesn't Matter...Or Does It?

, 18 Jun 2010
Rate this:
Please Sign up or sign in to vote.
When you use a List, it doesn't matter if you use the ForEach method of the generic list or use a normal foreach or does it? Sometimes it makes a difference!


In C#, you have various possibilities to iterate over a list like for loop, foreach loop or with LINQ. When you use a List(T) type you have even one more, the ForEach method. But this method doesn't always show the same behaviour as a normal foreach loop.

Using the Code

The ForEach method of the List<T> (not IList<T>) executes an operation for every object which is stored in the list. Normally it contains code to either read or modify every object which is in the list or to do something with list itself for every object.

Modify the Object Itself

The following sample with a ForEach method loops over all stored Points in the collection. It subtracts 10 from the x coordinate of the point. At the end, the Points will be printed to the console.

List<Point> points = new List<Point>(){ new Point(14, 10), new Point(19, 10) };

items.ForEach(point => point.X = point.X - 10);

foreach (Point point in points)

The output in the console is in this case {X=14, Y=10} and {X=19, Y=10}. I expected that X is 4 and 9, so what's wrong? If you put the same logic into a normal foreach statement, the compiler throws the following error: "Cannot modify members of 'point' because it is a 'foreach iteration variable'". If we define our own type, the code does what it should do!

public class MyPoint
   public MyPoint(int x, int y){ X = x; Y = y; }
   public int X{ get; set; }
   public int Y{ get; set; }

List<MyPoint> points = new List<MyPoint>(){ new MyPoint(14, 10), new MyPoint(19, 10) };

items.ForEach(point => point.X = point.X - 10);

foreach (MyPoint point in points)

The difference is, that Point is a value type, a struct, and MyPoint is a reference type. So in the case where Point is used, a copy of the object is passed to the method, not the object itself. So if the action, which is passed into the ForEach method, changes the copy, but it won't affect the original object.

Modify the Collection

When you use a normal foreach statement, you can't add or remove items while iterating over the collection. But with List.ForEach you can, so the following code can be executed without any errors. Which result do you expect?

public class Integer
    public int Value { get; set; }
    public Integer(int value) { Value = value; }

public void Sample()
    List<Integer> items = new List<Integer>() 
       new Integer(14), 
       new Integer(0), 
       new Integer(19) 

    items.ForEach(item =>
        if (item.Value == 0)
        item.Value = item.Value - 10;

    foreach (Integer item in items)

The result which is shown in the console is 4 and 19. So this is a good example of not all what you can do, you also should do! The result should be 4 and 9! It seems that internally a for loop is used, which iterates backward over the collection.

Points of Interest

So List<T>.ForEach allows several things which are blocked in a foreach loop. These things aren't allowed for a good reason. So if you want to store objects of value types, like int, long, double, bool or even string, in a generic List, you shouldn't use the ForEach method if you want to avoid problems. A good solution is to use a for loop and access the data over the indexer of the collection. Also removing items in the ForEach method is a thing which should be avoided when it is possible.


This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


About the Author

Mattia Baldinger
Software Developer
Switzerland Switzerland
No Biography provided

You may also be interested in...

Comments and Discussions

BugModify the Collection ??? Pin
Christian Del Bianco4-Dec-14 0:20
memberChristian Del Bianco4-Dec-14 0:20 
BugI DON'T think so! Pin
Sadiq Abdullah17-Dec-13 2:33
memberSadiq Abdullah17-Dec-13 2:33 
QuestionA Typical Grid View Problem Pin
Moumit Mondal18-May-12 4:47
memberMoumit Mondal18-May-12 4:47 
GeneralMy vote of 1 Pin
Jon Artus18-Jun-10 2:01
memberJon Artus18-Jun-10 2:01 
Generalforech vs. ForEach [modified] Pin
Tarabanko Yury15-Jun-10 1:53
memberTarabanko Yury15-Jun-10 1:53 
GeneralLearning to use .NET Pin
tonyt14-Jun-10 9:46
membertonyt14-Jun-10 9:46 
GeneralRe: Learning to use .NET Pin
Mattia Baldinger14-Jun-10 20:23
memberMattia Baldinger14-Jun-10 20:23 
GeneralRe: Learning to use .NET Pin
William E. Kempf15-Jun-10 11:04
memberWilliam E. Kempf15-Jun-10 11:04 
GeneralRe: Learning to use .NET Pin
Mattia Baldinger18-Jun-10 2:29
memberMattia Baldinger18-Jun-10 2:29 
GeneralNot a good idea Pin
Binoy Patel14-Jun-10 7:07
memberBinoy Patel14-Jun-10 7:07 
GeneralRe: Not a good idea Pin
William E. Kempf15-Jun-10 11:17
memberWilliam E. Kempf15-Jun-10 11:17 
GeneralNot using LINQ to it's advantage. Pin
James Curran14-Jun-10 5:14
memberJames Curran14-Jun-10 5:14 
GeneralRe: Not using LINQ to it's advantage. Pin
Jon Artus18-Jun-10 2:56
memberJon Artus18-Jun-10 2:56 
QuestionTypo? Pin
James Curran14-Jun-10 5:02
memberJames Curran14-Jun-10 5:02 
AnswerRe: Typo? Pin
Mattia Baldinger14-Jun-10 6:53
memberMattia Baldinger14-Jun-10 6:53 
GeneralRe: Typo? Pin
James Curran16-Jun-10 4:59
memberJames Curran16-Jun-10 4:59 
QuestionComparison in performance? Pin
zlezj14-Jun-10 4:54
memberzlezj14-Jun-10 4:54 
AnswerRe: Comparison in performance? Pin
Jon Artus18-Jun-10 2:03
memberJon Artus18-Jun-10 2:03 
GeneralRe: Comparison in performance? Pin
Jon Artus18-Jun-10 2:40
memberJon Artus18-Jun-10 2:40 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Terms of Use | Mobile
Web01 | 2.8.1802120.2 | Last Updated 18 Jun 2010
Article Copyright 2010 by Mattia Baldinger
Everything else Copyright © CodeProject, 1999-2018
Layout: fixed | fluid