【问题标题】:How can I iterate over a Xamarin.Forms.Maps Map.Pins list while modifying the list?如何在修改列表时迭代 Xamarin.Forms.Maps Map.Pins 列表?
【发布时间】:2020-07-28 16:47:40
【问题描述】:

我正在开发一个使用 Maps 包的 Xamarin.Forms 应用程序。 Map 对象包含一个 IList Pins,它存储包含 Label、Position 和其他属性的 Pin 对象列表。我试图通过将它们的位置与包含相同属性(ID、位置等)的自定义对象的集合进行比较来更新此 Pin 图列表,以及它们是否不再存在于此列表中,并相应地删除它们。

为了详细说明,每次更新时,我都想遍历 Pins 列表,删除不再与集合中的对象对应的所有引脚,添加与集合中的新对象对应的所有引脚,并更改相应对象的位置发生变化的任何引脚。

我试图通过迭代 Pins 并在必要时删除、添加和更改 Pins 时进行相应的比较来做到这一点。这里的问题是每次删除 Pin 时都会出现以下错误:

An exception of type 'System.InvalidOperationException' occurred in mscorlib.dll but was not handled in user code
Collection was modified; enumeration operation may not execute.

在修改正在迭代的列表时这是可以预料到的,但是所有可用的解决方案都可以解决这个问题,例如在实例化 foreach 循环时使用 Maps.Pins.ToList(),而使用 for 循环foreach 循环,甚至创建 Pins 列表的副本以在修改原始列表时进行迭代,都不能解决这个问题。

我知道其中一些解决方案有效,因为我在比较自定义对象列表时使用它们来解决此问题,但由于某种原因,它们似乎都不适用于 Map.Pins 列表。谁能指出我可能做错了什么,或者是否有一些关于 Map.Pins 列表的详细信息将其排除在这些解决方案之外?有没有其他方法可以解决这个问题?

以下是参考的方法,在代码中,我尝试实现“删除不应再存在的引脚”功能:

.ToList()

foreach (Pin pin in map.Pins.ToList())
            {
                if (!newList.Any(x => x.ID == pin.Label))
                {
                    Debug.WriteLine("Pin " + pin.Label + " is being removed.");
                    map.Pins.Remove(pin);
                }
            }

For循环

            for (int i = 0; i < map.Pins.Count; i++) {
                Debug.WriteLine(map.Pins[i].Label);
                if (!newList.Any(x => x.ID == map.Pins[i].Label))
                {
                    Debug.WriteLine("Pin " + map.Pins[i].Label + " is being removed.");
                    map.Pins.Remove(map.Pins[i]);
                }
            }

创建新列表

List<Pin> oldPins = new List<Pin>();

            foreach (Pin pin in map.Pins)
            {
                oldPins.Add(pin);
            }

foreach (Pin pin in oldPins)
            {
                if (!newList.Any(x => x.ID == pin.Label))
                {
                    Debug.WriteLine("Pin " + pin.Label + " is being removed.");
                    map.Pins.Remove(pin);
                }
            }

// I tried this with the for loop solution as well

提前非常感谢

【问题讨论】:

  • 在“for循环”方法中,您需要计算BACKWARDS,否则每次删除时您的索引都会出错。你的第三种方法应该有效,当你尝试它时会发生什么?
  • 我将尝试使用 for 循环反转索引。使用第三种方法,我得到相同的 InvalidOperationException
  • 使用递减 for 循环似乎有效。我不确定为什么其他解决方案没有。我将进行更多测试以确保其按预期工作,但与此同时,如果您想在答案中提出您的建议,我会接受它。

标签: list xamarin.forms collections invalidoperationexception xamarin.forms.maps


【解决方案1】:

为了让for循环方法起作用,你需要倒数,否则每次删除一个项目时你的索引都会被抛出。

【讨论】:

  • 在遍历 map.Pins 的同时使用 for 循环解决方案解决了这个问题。
猜你喜欢
  • 2014-09-17
  • 2017-12-05
  • 2018-10-12
  • 1970-01-01
  • 2019-04-04
  • 2012-06-04
  • 1970-01-01
相关资源
最近更新 更多