Click here to Skip to main content
15,909,440 members
Please Sign up or sign in to vote.
1.00/5 (1 vote)
See more:
Hi,
I have written the following code:

foreach (Object i in objStack)
                Console.WriteLine(" {0}", objStack.Pop());


But I am getting following error message:

Unhandled Exception: System.InvalidOperationException: Collection was modified; enumeration operation may not execute.
   at System.Collections.Stack.StackEnumerator.MoveNext()
   at Stack1.Program.Main(String[] args) in D:\PhD Courses ttu\C-Sharp\Stack1\Stack1\Program.cs:line 16


Some body please guide me.

Zulfi.

What I have tried:

I searched the web but I can't get any solution.
Posted
Updated 4-Jun-19 22:36pm

WHen you use a foreach loop, you set up and use something called an enumerator which returns each element in sequence as you go round the loop. If you change the object the enumerator is working on, it can't be sure which element to work on next, and so you get an error.
Effectively, the foreach loop sets up a for loop:
C#
int count = deck.Count;
for (int i = 0; i < count; i++)
    {
    Card c = deck[i];
    Console.WriteLine(c);
    }
If you start removing cards inside the loop:
C#
int count = deck.Count;
for (int i = 0; i < count; i++)
    {
    Card c = deck[i];
    if (c.IsSpade)
        {
        deck.Remove(c);
        }
    Console.WriteLine(c);
    }
Then it will cause two problems:
1) It will not print the card after the spade.
2) it will run off the end of the deck because the loop doesn't "know" that i shouldn't go that high anymore.
(foreach doesn't do it like that - it's rather more complicated internally - but the principle is the same)
You can't change the collection inside a foreach, or change the value of the foreach variable inside the loop.
Try this instead:
C#
while(objStack.Count > 0)
   {
   Console.WriteLine(" {0}", objStack.Pop());
   }

Or possibly:
C#
foreach (Object i in objStack)
   {
   Console.WriteLine(" {0}", i);
   }
 
Share this answer
 
Comments
BillWoodruff 5-Jun-19 4:00am    
+5 Best explanation of this I have seen. I'll append a rather obvious after-word.
Rather simple, foreach and enumerators are only a facility to scan an object like a stack. The problem is than it don't work if you change the stack as you scan it.
You have to build a loop without this facility by using something like stack.length, remember, every time you remove an element, the length change.
 
Share this answer
 
The "Occam's Razor" solution: objStack.Clear();

Note: a C# Stack, by design, is a Collection that has few of the (Linq Extension Method based) function options that you can use with other Collections.

If you need/want to remove items from a Stack that are not "on top," then you should probably not be using a Stack.
 
Share this answer
 
v2

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900