5.4. foreach Statement
A C# foreach works like a for loop, except it does not use the header
(initializer, condition, and iterator) for conditional looping flow control. Instead,
the foreach loop iterates through each element in a given sequence or collection of data and
runs a set of instructions once for each of the elements. In other words, the
foreach loop is used exclusively to loop through elements in an array
(or other data sets).
In the case of for loop in C#, the local loop variable refers to the index of an
array whereas, in the case of a foreach loop, the loop variable refers to
the values of the array.
In for loop, the loop variable is of type int. The reason for this is,
here the loop variable refers to the index position of the array. For the foreach
loop, the data type of the loop variable must be the same as the
type of the values stored in the array. For example, if you have a string array,
then the loop variable must be of type string.
The syntax of the foreach loop is:
foreach (type variableName in arrayName)
{
// code block to be executed
}
A foreach statement only works with an object that holds a sequence or collection of data.
We will see many more kinds of sequences later. For now we can illustrate
with a string, which is a sequence of characters. Observe and test the
following two pieces of code in csharprepl to see how foreach
differs from the for statement.
Say you want to print out some Unicode/ASCII code
for certain characters. To achieve that using C# for loop, the code could look like:
> string str = "ABCabc";
> for (int i = 0; i < 6; i++)
{
Console.WriteLine("Unicode for {0} is {1}", i, (int)str[i]);
}
Unicode for 0 is 65
Unicode for 1 is 66
Unicode for 2 is 67
Unicode for 3 is 97
Unicode for 4 is 98
Unicode for 5 is 99
>
As you can see, with a for loop, you refer to the individual characters by its index
and then cast it to int:
(int)str[i]
Since strings are considered as arrays consisting of char type characters, we can loop
through a string using a foreach statement using type char and cast to print out
the underlying int Unicode value of each character. To achieve the same results using
the foreach loop, the code would look like the following (pay attention to the local
loop variable char ch; type is required as usual):
> string str = "ABCabc";
foreach (char ch in str) {
Console.WriteLine("Unicode for {0} is {1}.", ch, (int)ch);
}
Unicode for A is 65.
Unicode for B is 66.
Unicode for C is 67.
Unicode for a is 97.
Unicode for b is 98.
Unicode for c is 99.
As you can see, in a foreach loop, we do not rely on array indexing to refer to the
elements. Instead, we refer to the elements directly with the local loop variable (ch)
declared with the type (char in this case).
As you see in the preceding example, the foreach heading feeds us one
character from str each time through, using the name ch
to refer to it. Since any new variable name must be declared with a type in C#,
so ch is preceded in the heading by its type, char. Then we can use
ch inside the body of the loop.
``foreach`` vs. for loop
Some of the advantages/disadvantages of foreach over the for loop are:
foreach not involve variable setup (iterates over each element of the array).
foreach are more concise and readable than the indexing
forstatement.
The foreach loop does have some limitations: [1]
They don’t keep track of the index of the item.
They cannot iterate backwards. The loop can only go forward in one step.
If you wish to modify the array, the foreach loop isn’t the most suitable option.
The foreach loop cannot execute two-decision statements at once.
Warning
If you have explicit need to refer to the indices of the items in the sequence,
then a foreach statement does not work for you.
5.4.1. break in foreach
With a foreach loop, which has no explicit continuation condition,
the break could be more clearly useful. Here is a variant if you do not care
about the specific location of the target:
bool found = false;
foreach (string s in a) {
if (s == target)
{
found = true;
break;
}
}
if (found) {
Console.WriteLine("Target found");
} else {
Console.WriteLine("Target not found");
}
Note that for the for and foreach loops, you could do all the same things
with while loops, which you will learn in subsequent chapters, but there
are many situations where foreach loops and for loops are more convenient
and easier to read.
Footnotes