Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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...? ^^ )

like image 392
GianT971 Avatar asked Oct 20 '11 15:10

GianT971


People also ask

Can we modify list in foreach?

Modify a C# collection with foreach by using a second collection. Since we cannot change a collection directly with foreach , an alternative is to use a second collection. To that second collection we then add new elements. This way we can still benefit from the simplicity that foreach offers.

Can we put condition in foreach?

No, a foreach simply works for each element.

Why is foreach loop read only?

That is because foreach is meant to iterate over a container, making sure each item is visited exactly once, without changing the container, to avoid nasty side effects.

Which is better for or foreach in C#?

The difference between for and foreach in C# is that for loop is used as a general purpose control structure while foreach loop is specifically used for arrays and collections. In brief, both helps to execute code repeatedly but foreach loop is more specific to arrays and collections.


2 Answers

foreach is a read only iterator that iterates dynamically classes that implement IEnumerable, each cycle in foreach will call the IEnumerable to get the next item, the item you have is a read only reference, you can not re-assign it, but simply calling item.Value is accessing it and assigning some value to a read/write attribute yet still the reference of item a read only reference.

like image 189
Mohamed Abed Avatar answered Oct 12 '22 17:10

Mohamed Abed


The second isn't doing the same thing at all. It's not changing the value of the item variable - it's changing a property of the object to which that value refers. These two would only be equivalent if item is a mutable value type - in which case you should change that anyway, as mutable value types are evil. (They behave in all kinds of ways which the unwary developer may not expect.)

It's the same as this:

private readonly StringBuilder builder = new StringBuilder();  // Later... builder = null; // Not allowed - you can't change the *variable*  // Allowed - changes the contents of the *object* to which the value // of builder refers. builder.Append("Foo"); 

See my article on references and values for more information.

like image 33
Jon Skeet Avatar answered Oct 12 '22 19:10

Jon Skeet