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
for
statement.
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