I’ve always been confused about this one. Consider the following loops:
int [] list = new int [] { 1, 2, 3 };
for (int i=0; i < list.Length; i++) { }
foreach (int i in list) { }
while (list.GetEnumerator().MoveNext()) { } // Yes, yes you wouldn't call GetEnumerator with the while. Actually never tried that.
- The [list] above is hard-coded. If the list was changed externally while the loop was going through iterations, what would happen?
- What if the [list] was a readonly property e.g.
int List{get{return(new int [] {1,2,3});}}? Would this upset the loop. If not, would it create a new instance in each iteration?
Well:
forloop checks againstlist.Lengthon each iteration; you don’t actually accesslistwithin the loop, so the contents would be irrevelantforeachloop only useslistto get the iterator; changing it to refer to a different list would make no difference, but if you modified the list itself structurally (e.g. by adding a value, if this were really aList<int>instead of anint[]), that would invalidate the iteratorFundamentally you need to understand the difference between the contents of an array vs changing which object a variable refers to – and then give us a very concrete situation to explain. In general though, a
foreachloop only directly touches the source expression once, when it fetches the iterator – whereas aforloop has no magic in it, and how often it’s accessed simply depends on the code – both the condition and the “step” part of theforloop are executed on each iteration, so if you refer to the variable in either of those parts, you’ll see any changes…