gpt4 book ai didi

c# - 为什么 foreach 在从 ListView 中删除项目时起作用,而在 ListBox 中不起作用?

转载 作者:太空狗 更新时间:2023-10-30 00:44:14 24 4
gpt4 key购买 nike

我已经开始学习 C#,但我对我发现的行为有些困惑。我试图弄清楚,为什么在一种情况下代码可以工作而在另一种情况下却不能:

foreach (ListViewItem l in listView1.SelectedItems) l.Remove();
foreach (object l in listBox1.SelectedItems) listBox1.Items.Remove(l);

第一个工作正常并且没有错误,但第二个抛出异常并显示集合已更改的信息。

谁能给我解释一下?

附言。在 ListView 的情况下,我正在调试代码并且集合 SelectedItems 正在更改,但即使它运行良好。

最佳答案

当我阅读 .NET 中的代码时,更具体地说是 ListBox.csListView.cs,它们有两个不同的类来保存它们的 SelectedItems 集合。

ListBox.csSelectedObjectCollection,它有这些成员:

private ListBox owner;
private bool stateDirty;
private int lastVersion;
private int count;

ListView.csSelectedListViewItemCollection,它只有这些成员:

private ListView owner;
private int lastAccessedIndex = -1;

因此,通过查看它,我想我可以推断出 ListBox 的集合是一个适当的枚举器,它跟踪列表中的任何更改和项目数。另一方面,ListView 似乎根本不关心这一点,它只跟踪枚举器的当前索引并简单地向前迈进。

因此 ListBox 会抛出异常,因为它会跟踪修改,而 ListView 不会。

编辑:ListBox.csSelectecObjectCollection 的 GetEnumerator 方法如下所示:

public IEnumerator GetEnumerator() {
return InnerArray.GetEnumerator(SelectedObjectMask);
}

ListView.csSelectedListViewItemCollection 的 GetEnumerator 方法如下所示:

public IEnumerator GetEnumerator() { 
if (owner.VirtualMode) {
throw new InvalidOperationException(SR.GetString(SR.ListViewCantAccessSelectedItemsCollectionWhenInVirtualMode));
}

ListViewItem[] items = SelectedItemArray;
if (items != null) {
return items.GetEnumerator();
}
else {
return new ListViewItem[0].GetEnumerator();
}
}

所以看起来 ListView 返回一个数组的枚举器,它是常量,而 ListBox 返回一个实际的枚举器作为其 InnerArray 项的过滤器。

我知道这不是你问的;但最好先将所有项目添加到临时列表中,然后再循环遍历它以删除内容,因为您永远都无法知道枚举器是如何在后端实现的,也不知道它们将来可能会如何变化.

关于c# - 为什么 foreach 在从 ListView 中删除项目时起作用,而在 ListBox 中不起作用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8379072/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com