Alex Rivera | Logout

Why can't we assign a foreach iteration variable, whereas we can completely modify it with an accessor?

Asked 2011-10-20T15:11:55.980
88

I was just curious about this: the following code will not compile, because we cannot modify a foreach iteration variable:

        foreach (var item in MyObjectList)
        {
            item = Value;
        }

But the following will compile and run:

        foreach (var item in MyObjectList)
        {
            item.Value = Value;
        }

Why is the first invalid, whereas the second can do the same underneath (I was searching for the correct english expression for this, but I don't remember it. Under the...? ^^ )

Edit
Report

1 Answer

6

It would be possible to make item mutable. We could change the way the code is produced so that:

foreach (var item in MyObjectList)
{
  item = Value;
}

Became equivalent to:

using(var enumerator = MyObjectList.GetEnumerator())
{
  while(enumerator.MoveNext())
  {
    var item = enumerator.Current;
    item = Value;
  }
}

And it would then compile. It would not however affect the collection.

And there's the rub. The code:

foreach (var item in MyObjectList)
{
  item = Value;
}

Has two reasonable ways for a human to think about it. One is that item is just a place-holder and changing it is no different to changing item in:

for(int item = 0; item < 100; item++)
    item *= 2; //perfectly valid

The other is that changing item would actually change the collection.

In the former case, we can just assign item to another variable, and then play with that, so there's no loss. In the latter case this is both prohibited (or at least, you can't expect to alter a collection while iterating through it, though it doesn't have to be enforced by all enumerators) and in many cases impossible to provide (depending on the nature of the enumerable).

Even if we considered the former case to be the "correct" implementation, the fact that it could be reasonably interpreted by humans in two different ways is a good enough reason to avoid allowing it, especially considering we can easily work around that in any case.

answered 2011-10-20T15:33:27.457

Your Answer