1

我在 Silverlight 工具包中看到过类似以下的代码,但无法理解如何安全地执行此操作:

private void ItemsSourceCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
    // Update the cache
    if (e.Action == NotifyCollectionChangedAction.Remove && e.OldItems != null)
    {
        for (int index = 0; index < e.OldItems.Count; index++)
        {
            _items.RemoveAt(e.OldStartingIndex);
        }
    }
}

如果您从说索引 5 中删除一个项目,这不会将_items索引 5 之后集合中每个项目的当前索引更改为比以前少一个吗?那么,像这段代码那样使用它们的“旧”索引持续删除项目是安全的吗?

我真的很想了解为什么会这样。

有任何想法吗?

4

1 回答 1

4

这段代码看起来像是从特定的起始索引中删除一组连续的项目。如果您仔细阅读 remove 调用:

_items.RemoveAt( e.OldStartingIndex );  

您会注意到它正在迭代地从常量索引中删除项目。这意味着它通过删除连续范围内的项目来折叠列表。这很可能是正确的——假设这是代码的意图。

循环按指示执行多次e.OldItems.Count。所以(大概)它被告知从给定索引开始删除多少项目。

作为一般做法,您必须小心如何从集合中删除项目,原因如下:

  1. 当您删除项目时,项目索引确实会发生变化。因此必须注意避免因项目索引位置移动而导致的错误。
  2. 在迭代列表时对其进行变异(如在 foreach 循环中或使用显式 IEnumerator)会导致异常。迭代时不能改变列表(添加或删除) - 它会使迭代器无效。
于 2009-12-10T18:32:35.410 回答