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
fororforeachis 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 theforeachuses more resources in iterations– Hebert Lima