Click here to Skip to main content
15,891,607 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hi,

I am getting an exception when I try to remove item in foreach loop.
Collection was modified; enumeration operation may not execute.

In this short article ( http://www.dotnetperls.com/invalidoperationexception[^] ) they say that it cant be done this way but instead I could implement remove method in my own Plane class. -> but that doesn't work.
Is it possible to do it(to REMOVE item within foreach loop?)

Any comments or suggestions are welcome. Thank you.


C#
// Developed by : XXX XXX

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Threading;

namespace MyApplication
{
    public partial class MainWindow : Window
    {
        // when dealing with time
        DispatcherTimer arrivalClock;
        List<Plane> planes = new List<Plane>();
        List<Plane> planesLanded = new List<Plane>();
        List<Plane> planesCrashed = new List<Plane>();
        Random rnd;

        public MainWindow()
        {
            rnd = new Random(System.Environment.TickCount);
            InitializeComponent();
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            arrivalClock = new DispatcherTimer();
            // set the tick interval (pick ranomly between 1 - 5 seconds)
            arrivalClock.Interval = new TimeSpan(0, 0, rnd.Next(1, 5));
            // every time a tick event happens execute the method
            arrivalClock.Tick += new EventHandler(arrivalClock_Tick);
            // all set start the clock now
            arrivalClock.Start();
        }

        void arrivalClock_Tick(object sender, EventArgs e)
        {
            if (planes.Count() != 0)
            {
                // first check for any crashed or landed planes
                foreach (Plane p in planes)
                {
                    if (p.Fuel <= 0)
                    {
                        planesCrashed.Add(p);
                        refreshCrashedList();
                    }
                    else if(p.Distance <= 0)
                    {
                        planesLanded.Add(p);
                        refreshLandedList();
                    }

                    planes.Remove(p);
                    //p.Remove();
                    refreshPlanesList();
                }

                // every existing plane in my list will travel while time passes so their fuel, distance and other properties will change
                foreach(Plane p in planes)
                {
                    p.goForward();
                }
            }

            planes.Add(new Plane());
            refreshPlanesList();
        }

        private void refreshPlanesList()
        {
            lbxLanded.Items.Clear();

            foreach (Plane p in planes)
            {
                lbxLanded.Items.Add(p);
            }
        }

        private void refreshCrashedList()
        {
            lbxCrashed.Items.Clear();

            foreach (Plane p in planesCrashed)
            {
                lbxCrashed.Items.Add(p);
            }
        }

        private void refreshLandedList()
        {
            lbxLanded.Items.Clear();

            foreach (Plane p in planesLanded)
            {
                lbxLanded.Items.Add(p);
            }
        }
    }
}



C#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace MyApplication
{
    class Plane
    {
        string callSign;
        byte noOfPassengers;
        int fuelOnBoard;
        int fuelSpent;
        decimal speed;
        decimal distance;
        DateTime arrivedTime;
        Random rnd = new Random();

        // my default / dynamic constructor (i could create anotherone that takes in parameters but there is no need)
        public Plane()
        {
            callSign = getName();
            noOfPassengers = getPassengers();
            fuelOnBoard = getFuelOnBoard();
            fuelSpent = getFuelSpent();
            speed = getSpeed();
            distance = getDistance();
            arrivedTime = DateTime.Now;
        }

        // public properties
        #region

        public int Fuel
        {
            get { return fuelOnBoard; } 
        }

        public decimal Distance
        {
            get { return distance; }
        }

        #endregion

        public override string ToString()
        {
            return String.Format("{0} : passengers = {1}, fuel = {2}, distance = {3}", callSign, noOfPassengers, fuelOnBoard, distance);
        }

        private string getName()
        {
            char c = (char)rnd.Next(65, 91);
            return c.ToString();
        }

        private byte getPassengers()
        {
            byte b = (byte)rnd.Next(0, 255);
            return b;
        }

        private int getFuelOnBoard()
        {
            int i = (int)rnd.Next(2000, 10000);
            return i;
        }

        private int getFuelSpent()
        {
            int i = (int)rnd.Next(200, 1000);
            return i;
        }

        private decimal getSpeed()
        {
            decimal d = (decimal)rnd.Next(140, 400);
            return d;
        }

        private decimal getDistance()
        {
            decimal d = (decimal)rnd.Next(1000, 10000);
            return d;
        }

        public void goForward()
        {
            fuelOnBoard -= rnd.Next(500, 800);
        }

        //public void Remove()
        //{
        //    this.Remove();
        //}
    }
}
Posted
Updated 11-Oct-13 8:42am
v2

You can loop and modify a dictionary using the collection of keys. Apply a foreach loop and use the key to get actual element from your dictionary, a little bit of code goes here:

C#
// Get collection of keys from dictionary into a list to loop through  	
List<int> keys = new List<int>(Dictionary.Keys);
            
// iterating key collection using for-each loop
foreach (int key in keys)
{ 
    // here we can modify values of dictionary using this key as index.    
    Dictionary[key] = Dictionary[key] - 1; 
            	
}


a well described post about this listed HERE
 
Share this answer
 
v2
No, its not possible, but what you can do is this:

C#
List<string> objects = new List<string>();

//Add your objects for each string 
List<string> removeMe = new List<string>();

foreach (string s in objects)
    if (s == "SomeUnwantedValue")
        removeMe.Add(s);

foreach (string s in removeMe)
    objects.Remove(s);

removeMe.Clear();


Not the same data types, but you get the pattern there, add it to another collection , then iterate through the other collection after you've gathered the objects you want to remove and remove it from the original collection.
 
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