Why are assignment operators (=) invalid in a foreach loop?

后端 未结 10 1190
栀梦
栀梦 2020-12-14 07:10

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

相关标签:
10条回答
  • 2020-12-14 07:56

    You cannot modify a list that is being looped through via a "ForEach".

    The best option is to simply create a temporary list to store the items you wish to use.

    0 讨论(0)
  • 2020-12-14 07:59

    Because you can't use a foreach loop to modify an array you're looping through. The loop iterates through the array, so if you try to modify what it's iterating through then unexpected behavior may occur. Furthermore, as Darin and DMan have pointed out, you're iterating through an IEnumerable which is itself read-only.

    PHP makes a copy of the array in its foreach loop and iterates through that copy, unless you use references, in which case you'll modify the array itself.

    0 讨论(0)
  • 2020-12-14 07:59

    It would be perfectly possible to let it be altered. However, what does this then mean? It would read like the underlying enumeration was modified, which it isn't (it would be possible to allow that too, but that has its own downsides).

    So you'd have code that people would naturally read as indicating something other than what has actually happened. Considering that the purpose of a computer language is primarily to be understood by people (compilers deal with the balance being set against them, unless you use assembly, machine code, or the appropriately named Brainf**k) this would indicate a flaw in the language.

    0 讨论(0)
  • 2020-12-14 08:00

    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";
    }
    
    0 讨论(0)
  • 2020-12-14 08:03

    Because an IEnumerable is readonly.

    0 讨论(0)
  • 2020-12-14 08:03

    In general, if you're trying to do this, you need to think long and hard about your design, because you're probably not using the best construction. In this case, the best answer would probably be

    string[] sArray = Enumerable.Repeat("Some assignment.\r\n", 5).ToArray();
    

    Higher level constructions are almost always usable instead of this kind of loop in C#. (And C++, but that's a whole other topic)

    0 讨论(0)
提交回复
热议问题