Why should I use foreach instead of for (int i=0; i<length; i++) in loops?

It seems like the cool way of looping in C# and Java is to use foreach instead of C style for loops.

Is there a reason why I should prefer this style over the C style?

I'm particularly interested in these two cases, but please address as many cases as you need to explain your points.

  • I wish to perform an operation on each item in a list.
  • I am searching for an item in a list, and wish to exit when that item is found.

Imagine that you're the head chef for a restaurant, and you're all preparing a huge omelette for a buffet. You hand a carton of a dozen eggs to each of two of the kitchen staff, and tell them to get cracking, literally.

The first one sets up a bowl, opens the crate, grabs each egg in turn - from left to right across the top row, then the bottom row - breaking it against the side of the bowl and then emptying it into the bowl. Eventually he runs out of eggs. A job well done.

The second one sets up a bowl, opens the crate, and then dashes off to get a piece of paper and a pen. He writes the numbers 0 through 11 next to the compartments of the egg carton, and the number 0 on the paper. He looks at the number on the paper, finds the compartment labelled 0, removes the egg and cracks it into the bowl. He looks at the 0 on the paper again, thinks "0 + 1 = 1", crosses out the 0 and writes 1 on the paper. He grabs the egg from compartment 1 and cracks it. And so on, until the number 12 is on the paper and he knows (without looking!) that there are no more eggs. A job well done.

You'd think the second guy was a bit messed in the head, right?

The point of working in a high-level language is to avoid having to describe things in a computer's terms, and to be able to describe them in your own terms. The higher-level the language, the more true this is. Incrementing a counter in a loop is a distraction from what you really want to do: process each element.


Further to that, linked-list type structures can't be processed efficiently by incrementing a counter and indexing in: "indexing" means starting over counting from the beginning. In C, we can process a linked list that we made ourselves by using a pointer for the loop "counter" and dereferencing it. We can do this in modern C++ (and to an extent in C# and Java) using "iterators", but this still suffers from the indirectness problem.


Finally, some languages are high-enough level that the idea of actually writing a loop to "perform an operation on each item in a list" or "search for an item in a list" is appalling (in the same way that the head chef shouldn't have to tell the first kitchen staff member how to ensure that all the eggs are cracked). Functions are provided that set up that loop structure, and you tell them - via a higher-order function, or perhaps a comparison value, in the searching case - what to do within the loop. (In fact, you can do these things in C++, although the interfaces are somewhat clumsy.)


Two major reasons I can think of are:

1) It abstracts away from the underlying container type. This means, for example, that you don't have to change the code that loops over all the items in the container when you change the container -- you're specifying the goal of "do this for every item in the container", not the means.

2) It eliminates the possibility of off-by-one errors.

In terms of performing an operation on each item in a list, it's intuitive to just say:

for(Item item: lst)
{
  op(item);
}

It perfectly expresses the intent to the reader, as opposed to manually doing stuff with iterators. Ditto for searching for items.


  • foreach is simpler and more readable

  • It can be more efficient for constructions like linked lists

  • Not all collections support random access; the only way to iterate a HashSet<T> or a Dictionary<TKey, TValue>.KeysCollection is foreach.

  • foreach allows you to iterate through a collection returned by a method without an extra temporary variable:

    foreach(var thingy in SomeMethodCall(arguments)) { ... }