为什么foreach在从ListView中删除项目时起作用而在ListBox中不起作用?
我开始学习C#,我对我发现的行为感到有点困惑。 我试着弄清楚,为什么在一种情况下代码工作而在另一种情况下不工作:
foreach (ListViewItem l in listView1.SelectedItems) l.Remove(); foreach (object l in listBox1.SelectedItems) listBox1.Items.Remove(l);
第一个工作正常,没有错误,但第二个抛出exception与集合被更改的信息。
有人能解释一下吗?
PS。 在ListView的情况下,我正在调试代码和集合SelectedItems正在改变,但即使它运作良好。
当我读取.NET中的代码,更具体地说是ListBox.cs
和ListView.cs
,它们有两个不同的类来保存它们的SelectedItems
集合。
ListBox.cs
有SelectedObjectCollection
,它有以下成员:
private ListBox owner; private bool stateDirty; private int lastVersion; private int count;
ListView.cs
具有SelectedListViewItemCollection
,它仅包含以下成员:
private ListView owner; private int lastAccessedIndex = -1;
因此,通过查看,我想我可以推断出ListBox
的集合是一个适当的枚举器,可以跟踪列表中的任何更改和项目数。 另一方面, ListView
似乎根本不关心它,只跟踪枚举器的当前索引并简单地前进。
所以ListBox
抛出exception,因为它跟踪修改, ListView
没有。
编辑 : ListBox.cs
的SelectecObjectCollection
的GetEnumerator方法如下所示:
public IEnumerator GetEnumerator() { return InnerArray.GetEnumerator(SelectedObjectMask); }
ListView.cs
的SelectedListViewItemCollection
的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项的filter。
我知道这不是你所问的; 但是在循环删除之前将所有项添加到临时列表总是有利的,因为你永远不知道枚举器是如何在后端实现的,也不知道它们将来如何改变。
while (myListBox.SelectedItems.Count > 0) { myListBox.Items.Remove(myListBox.SelectedItems[0]); }
您无法修改要枚举的集合。 这就是你在第二个例子中得到exception的原因。
ListView项上的Remove方法旨在在这种情况下不抛出exception。
上述就是C#学习教程:为什么foreach在从ListView中删除项目时起作用而在ListBox中不起作用?分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/cdevelopment/951633.html