C-Sharp | Java | Python | Swift | GO | WPF | Ruby | Scala | F# | JavaScript | SQL | PHP | Angular | HTML
Step 1: We create a string array with 3 elements—each the name of a common pet.
ArrayStep 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
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.
LINQStep 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
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
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 ExceptionC# 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.
Tip: Reverse is an extension method—this is a static method that uses special syntax like an instance method.
ExtensionStatic MethodAnd: 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
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
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'
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'
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'
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
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
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.
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.
Tip: We must specify the keyword "in" and the object to loop over. We can use a collection or array.