Strange behavior between foreach and loop

My Windows Phone 7 silverlight application, before placing buttons on the map layer, deletes everything that was there before.

I did this in the foreach loop as follows:

            //Clear previous pins
        try
        {
            foreach (UIElement p in PushPinLayer.Children)
            {
                if(p.GetType() == typeof(Pushpin))
                {
                    PushPinLayer.Children.Remove(p);
                }
            }
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
            //TODO: For some reason the foreach loop above causes an invalid Operation exception.
            //Cathing the error here until I can work out why it is happening.
        }

This code removes any pushpins as needed, but after the last loop throws an "Invalid Operation" exception, I rewrote it as a for loop:

        for (int i = 0; i < PushPinLayer.Children.Count; i++)
        {
            if (PushPinLayer.Children[i].GetType() == typeof(Pushpin))
            {
                PushPinLayer.Children.RemoveAt(i);
            }
        }

Which works fine, however I don't see why foreach throws an error.

+3
source share
6 answers

This is very normal

You cannot remove items from the list that you are still using in the foreach list. it’s better to delete the item to create a new list, and each time it is not a pushpin type, add the object to the new list.

, , .

, for , , , , , . for for , , , for. foreach , , .

+7

foreach Enumerator . , Enumerator , , . InvalidOperationException

- for .

    for (int i = PushPinLayer.Children.Count - 1; i >= 0 ; i--)
    {
        if (PushPinLayer.Children[i].GetType() == typeof(Pushpin))
        {
            PushPinLayer.Children.RemoveAt(i);
        }
    }

, Index i .

+3

, foreach, . , .

:

        List<UIElement> toRemove = new List<UIElement>();
        foreach (UIElement p in PushPinLayer.Children)
        {
            if(p.GetType() == typeof(Pushpin))
            {
                toRemove.Add(p);
            }
        }
        foreach(UIElement p in toRemove)
        {
            PushPinLayer.Children.Remove(p);
        }

RemoveAll, :

        PushPinLayer.Children.RemoveAll(p => p is Pushpin);
+2

, , LINQ-

var toRemove = PushPinLayer.Children.OfType<Pushpin>().ToList();
// since toRemove is a separate collection, it safe to do this now:
foreach (var child in toRemove)
   PushPinLayer.Children.Remove(child)
+2

, xxx.GetType() == typeof(Pushpin). , - , # -. :.

if (p is Pushpin) {...}
+2

You must not modify the collection while passing through it.

+1
source

Source: https://habr.com/ru/post/1779147/


All Articles