foreach
Syntax
These sections on foreach
loops and the later For Loops
introduce new looping statements.
Neither is absolutely necessary:
You could do all the same things with while
loops,
but there are many situations where foreach
loops and for
loops
are more convenient and easier to read.
A foreach
statement
only works with an object that holds a sequence or collection.
We will see many more kinds of sequences later. For now we can illustrate
with a string, which is a sequence of characters.
We have already processed strings a character at a time, with while
loops.
We took advantage of the fact that strings could be indexed. Our while
loops directly controlled the sequence of indices. Then we could
look up the character at each index of a given string s
:
int i = 0;
while (i < s.Length) {
code using the value of s[i]...
i++;
}
Examples have been in While-Statements with Sequences, like
// Print the characters of s, one per line.
static void OneCharPerLine(string s)
{
int i = 0;
while (i < s.Length) {
Console.WriteLine(s[i]);
i++;
}
}
In this example we really only care about the characters, not the indices. Managing the indices is just a way to get at the underlying sequence of characters.
A conceptually simpler view is just:
for each character in s
use the value of the character
To use “the character” in C#, we must be able to refer to it.
We might name the current character ch
.
The following is a variant of OneCharPerLine
with a foreach
loop:
static void OneCharPerLine(string s)
{
foreach (char ch in s) {
Console.WriteLine(ch);
}
}
That is all you need! The foreach
heading feeds us one
character from s
each time through, using the name ch
to refer to it.
Of course any new variable name must be declared in C#, so ch
is preceded in the heading by its type, char
.
Then we can use ch
inside the body of the loop.
Advancing to the next element in the sequence is automatic in the next
time through the loop. No i++
to remember;
no possibility of an infinite loop!
The general syntax of a foreach
loop is
foreach (
type itemName in
sequence ) {
}
Here is a version of IsDigits:
static Boolean IsDigits(string s)
{
foreach (char ch in s) {
if (ch < '0' || ch > '9') {
return false;
}
}
return (s.Length > 0);
}
See the advantages of foreach
in these examples:
They are more concise than the indexing versions.
They keep the emphasis on the characters, not the secondary indices.
The
foreach
heading emphasizes that an entire particular sequence is being processed.
Warning
If you have explicit need to refer to the indices of the items in the sequence,
then a foreach
statement does not work. Also a foreach
loop supplies the items in
a specific order; if you need a different order, it will not work.
Of course you can refer to the indices of items in sequence with a flexible
while
loop, or see For Loops, coming soon….