I’ll talk about collections, but understand that they are all sorts enumerable.
Semantics
It’s a semantic question. You’re going through a collection (array, list, string, dictionary, JSON structure, DB dataset, etc.)? Then the foreach
is well suited, he was made for it, he picks up the collection and analyzes item by item, it’s exactly what you want. It’s more convenient.
Security
It is usually safer, robust, reliable since it makes it hard to miss, some errors are impossible in it, and more readable because it indicates what it will do: scan a collection.
Don’t do what you need, conveniently
But it has its idiosyncrasies in it, too. He uses the collection immutably, if that’s what you want, and almost always is, he’s great, but if you need to modify the collection (I’m not talking about her items) there, today (I don’t know in the future), only the for
resolves for you.
Another idiosyncrasy is that it takes the value per copy and often you do operations that look like it’s a reference, but it’s not. But already there are structures by reference (ref
) that can minimize this.
Has collection that has no order and the foreach
is the only way to walk properly.
There are cases that need to do something that the foreach
can’t stand it, for example if you need a await
in the collection. But it has proposal to accept a foreach await
.
If you need scan the collection backwards no way to use the foreach
and it seems they don’t want to put a foreachreverse
in the language, despite the numerous proposals. Has palliative with cost.
Index
Another very important point is when you need index of the item. Some languages provide the index if you want in the foreach
, but most don’t offer it, so if you need it, there’s no way, the for
is your solution, it requires the use of an index variable for you to access the item manually. C# does not offer the index, one of the reasons to have the for
.
It is possible to create a structure where you pass a collection and receive the value of the item along with the index, then you could use the foreach
even in case you need the index, but the performance is worse and gets ugly (even if this is subjective).
using static System.Console;
using System.Linq;
public class Program {
public static void Main() {
var lista = new[] { "abc", "def", "ghi" };
foreach (var item in lista.Select((value, i) => (i, value ))) {
WriteLine($"{item.i} => {item.value}");
}
}
}
Behold working in the .NET Fiddle. And in the Repli.it. I put in the Github for future reference.
Flexibility
The for
"pure" is a slightly lower level mechanism and should be avoided but not reneged as many do. It has languages that even have a for
, some even the while
which has similar but not equal semantics. You can walk in steps in various ways. A for
is a while
"decked out", just by coincidence he sweeps a collection.
Performance
If you need it and the language offers better performance for that particular case using the for
in place of foreach
can be more interesting its use. It has to measure, after all if it needs the performance you have already made measurements. It is not to run pro faster without knowing if you need it and which one is faster. In many cases C# is as or faster using foreach
than doing manual, it can optimize better by eliminating unnecessary checks because it can prove that it will not access any improper item outside the existing track.
Has cases that the performance of foreach
can be much worse, depending on the enumerator used. There are cases that will even create an exponential algorithm unintentionally, and this is tragic. There is nothing trivial difference in a case like this. Of course you need to know how not to enter an O(n2) using the for
, is not simple, but at least it allows you to optimize (not in all cases, have problems that are exponential even).
Counting
If what you will sweep is not a collection then the for
probably be a more interesting option, after all you are doing a count, you are evolving a sequence, possibly creating a new collection, so it makes no sense to use a foreach
.
There’s a proposal for C# ter ranges, there the foreach
can be used even when you do not have a collection. Actually this can already be used with Enumerable.Range()
, but it’s usually weird to use it in most cases, it seems to me a force to use the foreach
where no need. In fact the creation of this method was for use with LINQ which has foreachs internal and needs a solution like this. In the end it didn’t help much when it was implemented, but the person has made some additions to be able to use the crease directly.
Just remember that a for
not just to make a count. Many people think only one for (var i = 0; i < c.Length; i++)
can be used, but any of the three parts can have almost anything, the first and third are statements, You wait for a boot there, but you can do other things, you can do several initializations, you can do nothing. The third is a step, can put whatever you want to be executed at each step of the repetition, in general it makes no sense to leave blank, but can. The second needs to be a boolean expression and can even be blank, although it is not very suitable. Even this works:
for (;;)
What does it do?
And note that for
or foreach
are commands and not functions so the "correct" is for ()
and not for()
. Both work the same, but the second seems to be a function, gives the wrong idea.
Completion
Although it works in any case, it has right and has wrong. You travel from Rio to SP by bike, car, truck, bus or plane, each has an advantage, there are guidelines to choose.
I think this difference in performance is so minimal, and it’s never the bottleneck in software, we usually do other things so grotesque that this is tiny.
– Dorathoto
@Dorathoto The doubt is not just about performance, I edited the question, to see if it became a little easier to enter what I want :)
– Vinícius Lima
If you could put a context, a code, a particularity, because, I think it’s more speculation than a fact, see, the question is good, but, will generate many opinions because it lacks the context of application. Use
for
orforeach
is more layout than right or wrong.– novic
I don’t know if it helps, but as a general rule I follow the following, when I don’t know how many elements I will iterate in the loop I use
foreach
, when I know how to useFor
, on the other hand theforeach
uses more resources in iterations– Hebert Lima