4 out of 10 rated this helpful - Rate this topic

List<T>.ForEach Method

Performs the specified action on each element of the List<T>.

Namespace:  System.Collections.Generic
Assembly:  mscorlib (in mscorlib.dll)
public void ForEach(
	Action<T> action
)

Parameters

action
Type: System.Action<T>
The Action<T> delegate to perform on each element of the List<T>.
Exception Condition
ArgumentNullException

action is null.

The Action<T> is a delegate to a method that performs an action on the object passed to it. The elements of the current List<T> are individually passed to the Action<T> delegate.

This method is an O(n) operation, where n is Count.

The following example demonstrates the use of the Action<T> delegate to print the contents of a List<T> object. In this example the Print method is used to display the contents of the list to the console.

Note Note

In addition to displaying the contents using the Print method, the C# example demonstrates the use of anonymous methods to display the results to the console.


using System;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
        List<String> names = new List<String>();
        names.Add("Bruce");
        names.Add("Alfred");
        names.Add("Tim");
        names.Add("Richard");

        // Display the contents of the list using the Print method.
        names.ForEach(Print);

        // The following demonstrates the anonymous method feature of C#
        // to display the contents of the list to the console.
        names.ForEach(delegate(String name)
        {
            Console.WriteLine(name);
        });
    }

    private static void Print(string s)
    {
        Console.WriteLine(s);
    }
}
/* This code will produce output similar to the following:
 * Bruce
 * Alfred
 * Tim
 * Richard
 * Bruce
 * Alfred
 * Tim
 * Richard
 */


.NET Framework

Supported in: 4, 3.5, 3.0, 2.0

.NET Framework Client Profile

Supported in: 4, 3.5 SP1

Portable Class Library

Supported in: Portable Class Library

Windows 7, Windows Vista SP1 or later, Windows XP SP3, Windows XP SP2 x64 Edition, Windows Server 2008 (Server Core not supported), Windows Server 2008 R2 (Server Core supported with SP1 or later), Windows Server 2003 SP2

The .NET Framework does not support all versions of every platform. For a list of the supported versions, see .NET Framework System Requirements.
Did you find this helpful?
(1500 characters remaining)
Community Content Add
Annotations FAQ
Variable Capture
Another difference between this ForEach method and a proper foreach loop, in C# 4 anyway, is that it behaves differently when you capture the iteration variable in a lambda, anonymous function, or LINQ query.

The classic example:
List<int> values = Enumerable.Range(0,10).ToList();
var actions = new List<Action>();
foreach(int i in values) { actions.Add(() => Console.WriteLine(i)); }
foreach(Action a in actions) { a(); }

This code prints 9 ten times because in C# 4, there is only one 'i' variable which is shared by every delegate, so they all print the final value of it (which is 9) when they execute.

The Foreach method equivalent behaves differently:
values.ForEach(i => actions.Add(() => Console.WriteLine(i)));

This has a new variable 'i' on each iteration, which is captured separately by the inner lambda, so the code prints out the numbers from 0 to 9, not just 10 9s.

I have read that C# 5 will change the foreach statement's behavior to match this method, which is all to the good. Until then, this is a reason you might prefer the ForEach method.
Concurrent Modification
There's a big differnce between this ForEach method and a foreach loop in C# or VB: the foreach loop winds up checking for concurrent modification. That is, if anything alters the list while you are looping over it, the List's enumerator implementation will throw an InvalidOperationException.

This does not happen with this here ForEach method. If you modify the list from inside the Action<T>, no exception occurs. The list may misbehave in this case: I've seen it just loop forever, but it does not seem to ever throw.

I expect this checking is the reason  why this ForEach method is actually faster than a proper foreach loop, even for a small list. I've done tests where this method runs faster than a loop for a 10-element list, which shows just how cheap that action delegate is. This is surprising: you'd expect the allocation and the virtual dispatch involved in using a delegate to weight more heavily, but it seems to not be the case.
Why not use Console.Writeline directly without the print method?
At least this works for me in Visual Studio 2010:

names.ForEach(Console.WriteLine);