For each using <list>

For each using <list>

Posted 14 December 2010 - 12:17 PM

If I missed this topic elsewhere, I apologize. I've been working on a tutorial that uses a <List> to hold the Monsters the Hero fights. When all the Monsters are dead, it uses a For each loop, to award gold and experience and it "clears" the monster. Then it seems to blow up in the For each loop, because the number has been altered. Any suggestions?

Re: For each using <list>

Posted 14 December 2010 - 11:34 PM

Hi,
you just put the end of you foreach-loop at the wrong position - it should end before making the output of how many exp and gold the player gets.
The Monster.Clear() and the whole piece of code is fine if you end the loop after line 11.

At the end it doesn't make no difference in this case if you loop from the end to the beginning or vice versa... And personally I prefer the Foreach-Loop cause its more clear for me at the first look and its not so "risky" e.g. by playing around with Index within the loop.

Re: For each using <list>

Zunera, in my reply it was a case of jumping on the obvious problem at hand, rather than seeing the bigger picture.

I guess using Dispose() doesn't disrupt the internal iterator of the collection?

Yeah sorry, i might have been a bit overreaction on this thread but your and insertAlias answers were describing the effect and not the cause - removing Monster.Clear() or putting it outside the loop would suppress the error but wouldn't solve the real problem, therefore it seemed very misleading to me.

And yes, in general the call of Dispose() has no effect on an iteration over the collection the object is in - but of course it always depends on the stuff that happens in the method if you are defining a custom Dispose() method.

If you loop from the start to the end - lets say 0 to 100, and dispose of the items as you move forward, yet still increment the counter... You skip every other entree. You may not notice this behavior during initial testing if you only have a couple Monsters in your list, or you fire it up, run a fast test then kill it. Its easy to overlook if you don't put in breakpoints and watch the variables pallet as the loop executes. If your list is Monsters: Bob, John, Mary, Ringo, Apollo, Yogi you have to be paying close attention to see you are only working on Monsters Bob, Mary, Apollo and somehow skipping Joh, Ringo and Yogi.

Then your loop increments the counter to 1 - but the current 1 is the old 2.

You have skipped the old 1 because it is now in position 0 and your counter has jumped over that.

This is the heart of the problem with using the ForEach loop construct and disposing of the lowest number index as you do so. Essentially a ForEach and For incrementing by +1 are the same thing. Which was the OP's original problem.

Dan064 said:

Then it seems to blow up in the Foreach loop, because the number has been altered

Re: For each using <list>

I realize with my pidly 594 reputation points that I'm no where near as qualified as you with your 10 points and 8 days of D.I.C. membership... but may I point out something?

You may and you did and i would give you a -1 but i let be this time - even if I'm very wondered that some admin just gave you a good reputation for your comment cause its totally wrong - like your last one.

Disposing an object doesn't remove it from a collection - there might be some special cases if the object may only exist as part of a collection, but for default List-objects you can call Dispose() without any effect on the list cause the object itself doesn't 'know' anything about a collection it might be part of. Try this:

This is the heart of the problem with using the ForEach loop construct and disposing of the lowest number index as you do so. Essentially a ForEach and For incrementing by +1 are the same thing. Which was the OP's original problem.

Dan064 said:

Then it seems to blow up in the Foreach loop, because the number has been altered

JackOfAllTrades and insertAlias already pointed out what the reason for the exception is - Monster.Clear() within the loop. And I already pointed out what the cause and the real problem of the given piece of code is.