[.net] Using a foreach loop to modify things?

Started by
7 comments, last by BradSnobar 17 years, 5 months ago
I was doing a little digging around in the msdn docs, and came across this:
Quote: The foreach statement is used to iterate through the collection to get the desired information, but should not be used to change the contents of the collection to avoid unpredictable side effects.
Now, without messing around with iterators and whatnot, is it possible (or is it safe) to modify the contents of a collection that is being iterated through by the foreach loop, or is it just best to use an iterator to change things? This is something that I hadn't thought about before...
Advertisement
I think what it means is not to change the size of the collection by inserting/deleting items while it's iterating through the collection.
Hey eedok? How is Edmonton doing?

So it is ok to change individual elements, but not to change the collection itself? Hmm. I might have to do some playing around with this.
Quote:Original post by Moe
Hey eedok? How is Edmonton doing?

So it is ok to change individual elements, but not to change the collection itself? Hmm. I might have to do some playing around with this.

It depends on the specific circumstances. For Each will create a copy of your elements, so the only way you can modify them is if you're storing references of some sort.

CM
There was an article a while ago on MSDN that talked about fiddling with foreach. It's a little crazy, but has some interesting implications. Eric Gunnerson discusses his favorite tips and trick for working with C#.

[Formerly "capn_midnight". See some of my projects. Find me on twitter tumblr G+ Github.]

Ah, thanks for the link capn_midnight!
I don't believe that foreach creates a copy.
As of Framework 2.0, using a foreach is much more efficient than a traditional for-loop, or any other loop for that matter.

It is recommended to only using foreach to read values.
You should not be modifying the iterating object within the foreach collection. In fact, i dont think the compiler will allow that.

bottom line: always use foreach, but don't modify things while your in it.
Quote:Original post by GekkoCube
I don't believe that foreach creates a copy.
As of Framework 2.0, using a foreach is much more efficient than a traditional for-loop, or any other loop for that matter.

It is recommended to only using foreach to read values.
You should not be modifying the iterating object within the foreach collection. In fact, i dont think the compiler will allow that.

bottom line: always use foreach, but don't modify things while your in it.


You should clarify that.


Foreach returns the value-object stored in the container, so you should not modify that value-object.

ie: in an array of int's:

foreach( int i in array )


You cannot modify i.

For an array of objects:

foreach( Foo f in array )


"f the value-object" is a reference to "f the reference", so you can modify the object that f points to to your hearts abandon... but you cannot change the actual reference to another object.

This is my signature. There are many like it, but this one is mine. My signature is my best friend. It is my life. I must master it as I must master my life. My signature, without me, is useless. Without my signature, I am useless.
Be aware that foreach hogs memory and is generally slower than a for loop.

It does have the potential as a construct to be much faster as we get more multiprocessor computers and the framework could take advantage of this in an iterator loop that is not controlled explicitly by the user.

Sadly, this is not currently the case. Though, thinking ahead to this eventuality is the only reason that I can see (other than complete stupidity) having an iterator that you can't really modify as a construct in a language.

perl for all of its faults, still lets you modify all kinds of things along these lines.

It's true that it is better now (in a few cases) in .net 2.0 than it was in the previous release. That is because some of the loops can be reduced to just plain for loops, and that's what the compiler does in those cases.

My opinion is that the compiler should do so in more cases than it does already.
Faster, leaner, code, using the same construct.

This topic is closed to new replies.

Advertisement