HomeSearch

C# foreach Loop Examples

Loop over elements with the foreach keyword. Compare other loops and review errors.
Foreach. On a beach there are many grains of sand. Each grain is separate—it is an element in a collection. The water nearby is calm and clear.
With a foreach loop, we evaluate each element individually. An index is not needed. With no indexes, loops are easier to write and programs are simpler.
A foreach-loop. Foreach accesses each element in order—this is called enumeration. We eliminate errors caused by incorrect index handling.

Step 1: We create a string array with 3 elements—each the name of a common pet.

Array

Step 2: We use foreach to loop through the elements in the array. Each element can be accessed with the identifier ("value") we choose.

Step 3: Inside the loop, we access the current string element. Foreach returns each element in order.

C# program that uses foreach over array using System; class Program { static void Main() { // Step 1: create an array of 3 strings. string[] pets = { "dog", "cat", "bird" }; // Step 2: loop with the foreach keyword. foreach (string value in pets) { // Step 3: access the enumeration variable. Console.WriteLine("FOREACH ITEM: " + value); } } } Output FOREACH ITEM: dog FOREACH ITEM: cat FOREACH ITEM: bird
Query. This example uses a foreach-loop to evaluate a LINQ expression. The expression sorts an array. Foreach causes a query to be evaluated.

Step 1: We create an array of 4 strings that are not sorted in any logical order.

Step 2: We specify a query expression. We use orderby to sort the strings. This expression is not evaluated yet—it is lazy.

LINQ

Step 3: With foreach, we evaluate the lazy query expression from step 2, and print each string. They are sorted alphabetically.

Tip: With the LINQ extensions the foreach keyword is important. Trying to use LINQ without it is frustrating.

C# program that uses query expression using System; using System.Linq; class Program { static void Main() { // Step 1: an unsorted string array. string[] letters = { "d", "c", "a", "b" }; // Step 2: use query to sort the array alphabetically. var sorted = from letter in letters orderby letter select letter; // Step 3: loop with the foreach keyword. foreach (string value in sorted) { Console.WriteLine(value); } } } Output a b c d
Var, implicit types. The var keyword can simplify our loop syntax. The example enumerates a Dictionary. The character count in "KeyValuePair" can be reduced.DictionaryKeyValuePair

Here: The foreach-loop uses var in its opening statement. The variable (var) is of type KeyValuePair(int, int).

C# program that uses var, foreach-loop using System; using System.Collections.Generic; class Program { static void Main() { // Add items to Dictionary. var data = new Dictionary<int, int>(); data.Add(1, 2); data.Add(2, 3); data.Add(3, 4); // Use var in foreach-loop. foreach (var pair in data) { Console.WriteLine("KEY, VALUE: {0}, {1}", pair.Key, pair.Value); } } } Output KEY, VALUE: 1, 2 KEY, VALUE: 2, 3 KEY, VALUE: 3, 4
List. The foreach construct elegantly loops through list elements. But it has a drawback. It restricts any mutations made to the collection during the loop.

Here: We use the foreach-loop construct to loop over each element in the List variable. All the integers are printed to the screen.

Restriction: We then try calling the Remove method. This fails because of a restriction of the foreach-loop.

Tip: If you want to add or remove elements during a loop, consider a for-loop. But be careful to maintain correct indexes.

InvalidOperation Exception
C# program that uses List, Remove 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.
Reverse. With the LINQ extensions, we can invoke a Reverse() method. We can then use foreach over the reversed results. This is a reversed foreach-loop of sorts.

Tip: Reverse is an extension method—this is a static method that uses special syntax like an instance method.

ExtensionStatic Method

And: Reverse() receives an IEnumerable collection, which includes arrays (string[]) and Lists.

Warning: This for each-reverse loop will have worse performance than a for-loop that decrements its index.

C# program that uses foreach-loop, Reverse using System; using System.Linq; class Program { static void Main() { // An example array. string[] array = { "bird", "frog", "dog", "snake" }; // Use the Reverse generic extension method. foreach (string value in array.Reverse()) { Console.WriteLine("REVERSE VALUE: " + value); } } } Output REVERSE VALUE: snake REVERSE VALUE: dog REVERSE VALUE: frog REVERSE VALUE: bird
For-loop. Let's compare loops. For has more complexity in its syntax. This gives it more power if you want to modify the collection or examine adjacent elements.

Tip: Optimizing compilers analyze loop variables in for-loops. The speed of loops is critical in many programs.

Note: In compiler theory, an expression that is based on a loop index such as "i" is called an affine expression.

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

C# program that uses for, foreach loops using System; class Program { static void Main() { // Array of color strings. string[] colors = { "red", "orange", "yellow", "green" }; // Print all colors with for-loop. Console.WriteLine(":::FOR:::"); for (int i = 0; i < colors.Length; i++) { // Assign string reference based on induction variable. string value = colors[i]; Console.WriteLine(value); } // Print all colors with for each. Console.WriteLine(":::FOREACH:::"); foreach (var value in colors) { Console.WriteLine(value); } } } Output :::FOR::: red orange yellow green :::FOREACH::: red orange yellow green
Error, cannot assign. We cannot assign the variable we use in a foreach-loop. To fix this error, we can add another local inside the loop—that local can be reassigned as much as we want.
C# program that shows cannot assign error class Program { static void Main() { foreach (int value in new int[] { 1, 2, 3 }) { value = 20; } } } Output Error CS1656 Cannot assign to 'value' because it is a 'foreach iteration variable'
Error, cannot operate. We cannot use a foreach statement on many kinds of variables such as tuples. An implementation of GetEnumerator (or IEnumerable) is always required.
C# program that shows cannot operate error using System; class Program { static void Main() { var tuple = new Tuple<int, int>(0, 0); // Cannot use foreach on tuple. foreach (int value in tuple) { } } } Output Error CS1579 foreach statement cannot operate on variables of type 'Tuple<int, int>' because 'Tuple<int, int>' does not contain a public instance definition for 'GetEnumerator'
Error, cannot convert type. When we specify the variable type in foreach, there must exist a conversion to it. Here the string "test" returns chars.

And: A char cannot be converted to a string implicitly (with no cast) so we get an error.

Tip: To fix this program, change the string keyword in "foreach" to char (or int, which has a conversion from a char).

C# program that shows cannot convert type error class Program { static void Main() { string test = "bird"; // The foreach variable must have a conversion. foreach (string value in test) { } } } Output Error CS0030 Cannot convert type 'char' to 'string'
Benchmark, local array. How can we improve the iteration performance of a foreach-loop? The foreach-loop is often less efficient than a simple for-loop.

Version 1: This version of the code uses a foreach-loop that directly accesses the instance field _values.

Version 2: This code stores the instance field into a local variable reference. Then it uses the local in a foreach-loop.

Result: Because the field's address is resolved each time it is accessed, Method1() is slower. It adds indirection.

C# program that times foreach-loop using System; using System.Diagnostics; class Program { const int _max = 100000000; static void Main() { Program program = new Program(); // Version 1: use foreach-loop on field. var s1 = Stopwatch.StartNew(); for (int i = 0; i < _max; i++) { program.Method1(); } s1.Stop(); // Version 2: use foreach-loop on local. 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")); } 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: foreach, field 2.26 ns: foreach, local variable
Benchmark, for and foreach. There is sometimes a performance difference when using foreach instead of for. This probably depends highly on the system being tested.

Version 1: This code sums the elements of an int array by using a for-loop. The sum is returned.

Version 2: This version uses the foreach-loop. It sums the elements just like the other version.

Result: In current tests, foreach is faster than the for-loop (even when the order of the tests is reversed).

Tip: If the value of each element is accessed, the foreach-loop tends to do well in comparison to the for-loop.

C# program that times for, foreach loops using System; using System.Diagnostics; class Program { static int Method1(int[] array) { // Uses for. int sum = 0; for (int i = 0; i < array.Length; i++) { sum += array[i]; } return sum; } static int Method2(int[] array) { // Uses foreach. int sum = 0; foreach (int value in array) { sum += value; } return sum; } static void Main() { int[] array = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 }; Method1(array); Method2(array); // Version 1: use for. var s1 = Stopwatch.StartNew(); const int max = 100000000; for (int i = 0; i < max; i++) { if (Method1(array) == 0) { return; } } s1.Stop(); // Version 2: use foreach. var s2 = Stopwatch.StartNew(); for (int i = 0; i < max; i++) { if (Method2(array) == 0) { return; } } s2.Stop(); Console.WriteLine(((double)(s1.Elapsed.TotalMilliseconds * 1000000) / max).ToString("0.00 ns")); Console.WriteLine(((double)(s2.Elapsed.TotalMilliseconds * 1000000) / max).ToString("0.00 ns")); } } Output 5.33 ns for 4.04 ns foreach
Performance, notes. With foreach, we always have a local variable that has each element's value. If this value is used, foreach tends to perform better than for.

But: If the element value is not used, copying the value into a local variable will likely cause a performance decrease.

Sometimes: The foreach-loop can be used in a way that we cannot use a for-loop. It interacts with the yield keyword.

And: This can enhance performance—it can delay or avoid computations. But it can also reduce performance.

Notes, errors. A compile-time error is caused when we try to compile a program that incorrectly uses a foreach iteration variable. Foreach variables are read-only.

And: The C# compiler detects this kind of error before it ever causes a problem.

Tip: If we need to change data in a loop, a for-loop is often a better choice. With for, we can directly assign elements.

Arrays, strings. The foreach-loop is versatile. We use it on strings, string arrays, and even DataTables. These are collections that stored as representations in memory.Foreach: String ArrayForeach: String CharsForeach: DataTable
GetEnumerator. When designing a collection that is likely to be widely used in other code, you can implement this method. This enables the foreach-loop.GetEnumerator
IEnumerable. If a class implements IEnumerable, we can use the foreach-loop upon it. Many things, like Lists and arrays, implement this generic interface.IEnumerable
Keywords. Foreach is a reserved keyword. The iteration variable "string value" can be a different type. For example, we can use "int number" when looping over ints.

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

Yield. This feature allows the position in the control flow to be remembered and resumed when the statement finishes. It is implemented in terms of simpler constructs.Yield
Control statements. In the flow of control, instructions proceed in order, unless a branch transfers control to an offset. These keywords are supported in foreach-loops.BreakContinueGotoReturn
More loops. Here are other loops we can use. For known ranges of numbers, for is best. For an infinite loop, or one with no known termination, while is ideal.ForWhileDo
A summary. Foreach is a powerful, concise, beautiful loop. It uses the "in" keyword and reads like a sentence—and reduces possible bugs. It handles arrays and works well with queries.
Home
Dot Net Perls
© 2007-2020 Sam Allen. Every person is special and unique. Send bug reports to info@dotnetperls.com.