List 枚举的意外 'Collection was modified; enumeration operation may not execute.' 异常,尽管 List 未被修改

Unexpected 'Collection was modified; enumeration operation may not execute.' exception for List enumeration, despite List not being modified

我的代码中出现异常“System.InvalidOperationException: 'Collection was modified; enumeration operation may not execute.'”。我明白异常是什么,但我不明白的是为什么我要根据我的代码得到它。

public static void DiffCircles(Circle original, Circle toSubtract)
        {
            List<Vector2> originalAreaCopy = original.area;
            foreach(Vector2 oArea in original.area) -- **Exception occurs here on the second iteration**
            {
                foreach(Vector2 tsArea in toSubtract.area)
                {
                    if(oArea.X == tsArea.X && oArea.Y == tsArea.Y)
                    {
                        originalAreaCopy.Remove(originalAreaCopy[original.area.IndexOf(oArea)]);
                    }
                }
            }
            original.area = originalAreaCopy;
        }

最初我一直在通过在 if 语句中执行 original.area.Remove(oArea) 来删除重叠的 vector2。我得到了异常,然后查找它,并意识到我为什么得到它。所以我想如果我制作一个复制列表,从复制列表中删除重叠部分,然后在嵌套循环结束后将原始列表设置为等于复制列表,我会没事的。但是,令人惊讶的是,我仍然得到异常。

谁能解释为什么我仍然收到此错误?我不再在循环期间修改集合,所以我认为这会起作用,但由于某种原因它不起作用...

谢谢!

你的困惑源于这个假设:

So I figured if I made a copy list

List<Vector2> originalAreaCopy = original.area;

这实际上并没有复制列表,而是复制了 reference 到它。引用类型变量仅存储对对象的引用,因此在这种情况下,您现在有两个变量都引用同一个对象,即列表 original.areaoriginalAreaCopy.

因此,当您稍后从列表中删除一个对象时,通过 originalAreaCopy,它仍然是您正在迭代的完全相同的列表,通过 original.area。但是,您仍然只有一个列表 object.

为了复制列表而不仅仅是对它的引用,最简单的方法可能就是这样做:

List<Vector2> originalAreaCopy = original.area.ToList();

这将构建一个包含 original.area 中所有元素的新列表,所以现在 original.areaoriginalAreaCopy 实际上 引用了两个不同的列表对象。