Why are assignment operators (=) invalid in a foreach loop?  I'm using C#, but I would assume that the argument is the same for other languages that support foreach (e.g. PHP).  For example, if I do something like this:
string[] sArray = new string[5];
foreach (string item in sArray)
{
   item = "Some assignment.\r\n";
}
I get an error, "Cannot assign to 'item' because it is a 'foreach iteration variable'."
Here's your code:
foreach (string item in sArray)
{
   item = "Some assignment.\r\n";
}
Here's a rough approximation of what the compiler does with this:
using (var enumerator = sArray.GetEnumerator())
{
    string item;
    while (enumerator.MoveNext())
    {
        item = enumerator.Current;
        // Your code gets put here
    }
}
The IEnumerator<T>.Current property is read-only, but that's not actually relevant here, as you are attempting to assign the local item variable to a new value. The compile-time check preventing you from doing so is in place basically to protect you from doing something that isn't going to work like you expect (i.e., changing a local variable and having no effect on the underlying collection/sequence).
If you want to modify the internals of an indexed collection such as a string[] while enumerating, the traditional way is to use a for loop instead of a foreach:
for (int i = 0; i < sArray.Length; ++i)
{
    sArray[i] = "Some assignment.\r\n";
}
                        Because the language specification says so.
But seriously, not all sequences are arrays or things that can be logically modified or written to. For instance:
foreach (var i in Enumerable.Range(1, 100)) {
   // modification of `i` will not make much sense here.
}
While it would've been technically possible to have i = something; modify a local variable, it can be misleading (you may think it really changes something under the hood and it wouldn't be the case). 
To support these kind of sequences, IEnumerable<T> doesn't require a set accessor for its Current property, making it read-only. Thus, foreach cannot modify the underlying collection (if one exists) using the Current property.
The foreach loop is designed to iterate through objects in a collection, not to assign things- it's simply design of the language.
Also, from MSDN:
"This error occurs when an assignment to variable occurs in a read- only context. Read-only contexts include foreach iteration variables, using variables, and fixed variables. To resolve this error, avoid assignments to a statement variable in using blocks, foreach statements, and fixed statements."
The foreach keyword just enumerates IEnumerable instances (getting an IEnumerator instances by calling the GetEnumerator() method). IEnumerator is read-only, therefore values can't be changed using IEnumerator =can't be changed using the foreach context.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With