[ACCEPTED]-Why is foreach loop Read-Only in C#-loops
That is because foreach is meant to iterate 20 over a container, making sure each item 19 is visited exactly once, without changing 18 the container, to avoid nasty side effects.
See: foreach in MSDN
If 17 you meant why would changes to an element 16 like an integer not affect a container of 15 integers, well this is because the variable 14 of iteration in this case would be a value 13 type and is copied, e.g.:
// Warning: Does not compile
foreach (int i in ints)
{
++i; // Would not change the int in ints
}
Even if the variable 12 of iteration was a reference type, whose 11 operations returned a new object, you wouldn't 10 be changing the original collection, you 9 would just be reassigning to this variable 8 most of the time:
// Warning: Does not compile
foreach (MyClass ob in objs)
{
ob=ob+ob; // Reassigning to local ob, not changing the one from the original
// collection of objs
}
The following example has 7 the potential to actually modify the object 6 in the original collection by calling a 5 mutating method:
// Warning: Does not compile
foreach (MyClass ob in objs)
{
ob.ChangeMe(); // This could modify the object in the original collection
}
To avoid confusion with regard to 4 value vs reference types and the scenarios 3 mentioned above (along with some reasons 2 related to optimization), MS chose to make 1 the variable of iteration readonly
.
Because the current element is returned 10 by value(i.e. copied). And modifying the 9 copy is useless. If it is a reference type 8 you can modify the content of that object, but 7 can't replace the reference.
Perhaps you 6 should read the documentation of IEnumerable<T>
and IEnumerator<T>
. That 5 should make it clearer. The most important 4 bit is that IEnumerable<T>
has a property Current
of type T
. And 3 this property has only a getter, but no 2 setter.
But what would happen if it had a 1 setter?
- It would work well with arrays and Lists
- It wouldn't work well with complex containers like hashtables, ordered list because the change causes larger changes in the container(for example a reordering), and thus invalidates the iterator. (Most collections invalidate the iterators if they get modified to avoid inconsistent state in the iterators.)
- In LINQ it does make no sense at all. For example with
select(x=>f(x))
the values are results of a function and have no permanent storage associated. - With iterators written with the
yield return
syntax it doesn't make sense either
foreach
is designed to visit each item in a collection 7 exactly once, and does not use an explicit 6 "loop index"; if you want more control over 5 the loop and have a loop index, use for
.
EDIT: You 4 can change the items in the collection being 3 iterated on inside a foreach
loop. For example:
foreach(Chair ch in mychairs)
{
ch.PaintColour = Colour.Green; //this alters the chair object *in* the collection.
}
You 2 cannot, however, add or remove items to/from 1 the collection.
More Related questions
We use cookies to improve the performance of the site. By staying on our site, you agree to the terms of use of cookies.