C# Foreach

Foreach loop construct

Foreach is a loop construct. It does not use an integer index. Instead, it is used on a collection and returns each element in order. This is called enumeration. It eliminates errors caused by incorrect index handling.

Example

Array type

We first use the keyword foreach on a string array to loop through the elements in the array. In the foreach-statement, you do not need to specify the loop bounds minimum or maximum. You do not need an "i" variable as in for-loops.

String Array

Note:This results in fewer characters to type and code that it is easier to review and verify, with no functionality loss.

Program that uses foreach over array: C#

using System;

class Program
{
    static void Main()
    {
	// Use a string array to loop over.
	string[] ferns =
	{
	    "Psilotopsida",
	    "Equisetopsida",
	    "Marattiopsida",
	    "Polypodiopsida"
	};
	// Loop with the foreach keyword.
	foreach (string value in ferns)
	{
	    Console.WriteLine(value);
	}
    }
}

Output

Psilotopsida
Equisetopsida
Marattiopsida
Polypodiopsida
Note

We see that the foreach-statement contains the reserved "foreach" keyword. The iteration variable "string value" can be a different type such as "int number" if you are looping over that type.

Tip:You must specify the keyword "in" and then the object to loop over. You can use a collection or array.

LINQ

LINQ: language integrated query

This example uses a foreach-loop that evaluates a LINQ expression. The expression sorts an array. The LINQ extension provides queries that are evaluated lazily. The sorting in the example won't occur until the foreach-loop is executed.

Program that uses foreach with LINQ query: C#

using System;
using System.Linq;

class Program
{
    static void Main()
    {
	// An unsorted string array.
	string[] letters = { "d", "c", "a", "b" };
	// Use LINQ query syntax to sort the array alphabetically.
	var sorted = from letter in letters
		     orderby letter
		     select letter;
	// Loop with the foreach keyword.
	foreach (string value in sorted)
	{
	    Console.WriteLine(value);
	}
    }
}

Output

a
b
c
d

With the LINQ extensions the foreach keyword is critical. It provides a greater level of abstraction over loop enumeration than a for-loop with an induction variable. Trying to use LINQ without foreach is frustrating.

Var

Var keyword

Using the var keyword in foreach loops is not in many examples. It can simplify your loop syntax. Let's compare a foreach-loop with the var keyword used in the enumeration statement, with a standard foreach-loop.

Next:The example enumerates a Dictionary. We see how the character count in "KeyValuePair" can be reduced.

VarKeyValuePairDictionary
Program that uses foreach var loop: C#

using System;
using System.Collections.Generic;

class Program
{
    static Dictionary<int, int> _f = new Dictionary<int, int>();

    static void Main()
    {
	// Add items to dictionary.
	_f.Add(1, 2);
	_f.Add(2, 3);
	_f.Add(3, 4);

	// Use var in foreach loop.
	foreach (var pair in _f)
	{
	    Console.WriteLine("{0},{1}", pair.Key, pair.Value);
	}
    }
}

Output

1,2
2,3
3,4

Program that uses foreach loop: C#

using System;
using System.Collections.Generic;

class Program
{
    static Dictionary<int, int> _h = new Dictionary<int, int>();

    static void Main()
    {
	// Add items to dictionary.
	_h.Add(5, 4);
	_h.Add(4, 3);
	_h.Add(2, 1);

	// Standard foreach loop.
	foreach (KeyValuePair<int, int> pair in _h)
	{
	    Console.WriteLine("{0},{1}", pair.Key, pair.Value);
	}
    }
}

Output

5,4
4,3
2,1
Steps

In this example, the first loop uses var in the foreach loop. The var actually is of type KeyValuePair(int, int). We see that specifying the entire generic name could make code less clear.

Tip:The var keyword here substitutes for a type that never actually appears in the program.

The second loop is the standard foreach syntax. The enumeration variable is fully specified. The syntax of the foreach conditional is much longer. As source text length increases, the likelihood of typos increases.

List

List type

We next loop through the elements in a List. The foreach loop construct provides a way to elegantly loop through elements, but it has a drawback. It restricts any mutations made to the collection during the loop.

We use the foreach-loop construct to loop over each element in the List variable. All the integers are printed to the screen. We then try calling the Remove method. This fails because of a restriction of the foreach-loop.

Program that uses list and foreach loop: C#

using System;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
	List<int> list = new List<int>();
	list.Add(1);
	list.Add(2);
	list.Add(3);
	// Loop over list elements using foreach-loop.
	foreach (int element in list)
	{
	    Console.WriteLine(element);
	}
	// You can't remove elements in a foreach-loop.
	try
	{
	    foreach (int element in list)
	    {
		list.Remove(element);
	    }
	}
	catch (Exception ex)
	{
	    Console.WriteLine(ex.Message);
	}
    }
}

Output

1
2
3
Collection was modified; enumeration operation may not execute.
Squares

You cannot remove elements inside a foreach-loop because the looping mechanism requires that state be saved. The runtime cannot tell if you removed an element that was to be looped over in a subsequent iteration.

InvalidOperationException

Note:If you remove elements that are already looped over, this wouldn't cause any problems. The runtime disallows this to be safe.

The foreach loop construct on the List type provides an elegant and simple way to loop over all elements in the collection. It has a limitation. You cannot change the layout of the collection during the loop.

Tip:If you want to add or remove elements during a loop, you could use a for-loop construct—but be careful to maintain correct indexes.

For

For loop

We next see that the for-loop has more complexity in its syntax, but this also gives it more power if you want to modify the collection or examine adjacent elements in the array. The best loop is determined by how it is used.

Program that uses for-loop and foreach-loop: C#

using System;

class Program
{
    static void Main()
    {
	// Array of rabbits names.
	string[] rabbits =
	{
	    "Forest Rabbit",
	    "Dice's Cottontail",
	    "Brush Rabbit",
	    "San Jose Brush Rabbit"
	};

	// Loop through string array with a for-loop.
	for (int i = 0; i < rabbits.Length; i++)
	{
	    // Assign string reference based on induction variable.
	    string value = rabbits[i];
	    Console.WriteLine(value); // Write the value.
	}

	// Loop through the string array with a foreach-loop.
	foreach (var value in rabbits)
	{
	    Console.WriteLine(value); // Write the value.
	}
    }
}

Output

Forest Rabbit
Dice's Cottontail
Brush Rabbit
San Jose Brush Rabbit
(... Repeated.)
Lowercase i

Optimizing compilers analyze loop variables in for-loops. The speed of loops is critical in many programs. In compiler theory, an expression that is based on a loop index such as "i" is called an affine expression.

Also:The loop iteration variables, such as "i", are considered induction variables.

Then:The compiler then uses strength reduction techniques to transform slow multiplications into fast additions.

Dragon Book: Compilers

Compile-time error

Warning: exclamation mark

A compile-time error is caused when you try to compile a program that incorrectly uses a foreach iteration variable. Foreach variables are read-only. The C# compiler detects this kind of error before it ever causes a problem.

Tip:If you want to change the data in a loop, using a for-loop is often a better choice. With it you can directly assign elements.

Error:Cannot assign to value because it is a foreach iteration variable.
(Visual Studio Error.)

Uses

C# programming language

There are many other examples of how you can use foreach-loops in your C# programs. This site contains examples for many loops over many types of collections. The foreach-loop is versatile.

Loop Over String ArrayLoop Over String CharsIn

GetEnumerator

When designing a collection that is likely to be widely used in other code, you can implement the GetEnumerator method. This enables the foreach-loop to automatically be able to loop over the data in your collection.

Note:This is implemented in the Framework collections in System.Collections.Generic. One example is found on the Dictionary.

Dictionary GetEnumerator

Yield

Yield keyword

There is a powerful feature that describes enumerators with a shorthand syntax. This feature is the yield keyword. Yield is combined with the break and return keywords. It provides a way to re-enter a function in its body.

The C# compiler generates a lot of code when you use yield. The keyword yield is contextual. This means it is used to provide this function when the compiler thinks that is the program's intention.

Yield

Performance

Performance optimization

There are performance issues with the foreach-loop versus the for-loop. Foreach has at best equivalent performance in regular looping conditions. Its main benefit is not in performance but in syntax.

Sometimes, the foreach-loop can be used in a way that you cannot use a for-loop, such as with the yield keyword. This can enhance performance by delaying or avoiding computations. It can also reduce performance.

Tip:I recommend foreach when writing less important parts of programs, but prefer the for-loop for hot loops as a precaution.

For

Benchmark

Question and answer

How can we improve the iteration performance of a foreach-loop? The foreach-loop is often less efficient than a simple for-loop. There are cases where improving the efficiency of a foreach-loop is useful.

This program uses two foreach-loops. Method1 uses a foreach-loop that directly accesses the instance field _values. Method2 stores the instance field into a local variable reference. Then it uses that local variable in the foreach-loop.

Note:Because the field's address must be resolved each time it is accessed, the Method1 version is slower. It adds indirection.

Program that tests foreach-loop performance: C#

using System;
using System.Diagnostics;

class Program
{
    const int _max = 100000000;
    static void Main()
    {
	Program program = new Program();
	var s1 = Stopwatch.StartNew();
	for (int i = 0; i < _max; i++)
	{
	    program.Method1();
	}
	s1.Stop();
	var s2 = Stopwatch.StartNew();
	for (int i = 0; i < _max; i++)
	{
	    program.Method2();
	}
	s2.Stop();
	Console.WriteLine(((double)(s1.Elapsed.TotalMilliseconds * 1000 * 1000) /
	    _max).ToString("0.00 ns"));
	Console.WriteLine(((double)(s2.Elapsed.TotalMilliseconds * 1000 * 1000) /
	    _max).ToString("0.00 ns"));
	Console.Read();
    }

    int[] _values = { 1, 2, 3 };

    int Method1()
    {
	// Access the field directly in the foreach expression.
	int result = 0;
	foreach (int value in this._values)
	{
	    result += value;
	}
	return result;
    }

    int Method2()
    {
	// Store the field into a local variable and then iterate.
	int result = 0;
	var values = this._values;
	foreach (int value in values)
	{
	    result += value;
	}
	return result;
    }
}

Output

3.86 ns
2.26 ns

The version that uses the field reference inside the foreach-loop requires 1.7 times more clock cycles for execution. Storing all variables in the foreach-loop iteration expression as local variables is faster.

Tip:The performance benefit to this local variable foreach-loop optimization may seem small, but it does influence execution time.

And:The optimization may not be directly practical. But it illustrates how the memory model in the .NET Framework works.

Summary

We saw examples of using foreach-loops. We discovered how to loop over an array. Then we used the foreach-loop with a LINQ expression. We performed a comparison of the for-loop and foreach-loop. And we caused a compile-time error.


C#: Loop