Woj*_*lik 4 c# foreach listview listbox
我开始学习C#,我对我发现的行为感到有点困惑.我试着弄清楚,为什么在一种情况下代码工作而在另一种情况下不工作:
foreach (ListViewItem l in listView1.SelectedItems) l.Remove();
foreach (object l in listBox1.SelectedItems) listBox1.Items.Remove(l);
Run Code Online (Sandbox Code Playgroud)
第一个工作正常,没有错误,但第二个抛出异常的信息,集合被更改.
有谁可以向我解释一下?
PS.在ListView的情况下,我正在调试代码和集合SelectedItems正在改变,但即使它运作良好.
当我看到里面的.NET代码,更具体ListBox.cs和ListView.cs,他们有保持他们的两个不同的类SelectedItems集合.
ListBox.cs有SelectedObjectCollection,有这些成员:
private ListBox owner;
private bool stateDirty;
private int lastVersion;
private int count;
Run Code Online (Sandbox Code Playgroud)
ListView.cs有SelectedListViewItemCollection,只有这些成员:
private ListView owner;
private int lastAccessedIndex = -1;
Run Code Online (Sandbox Code Playgroud)
因此,通过观察,我想我可以推断出该ListBox集合是一个合适的枚举器,可以跟踪列表中的任何更改和项目数.
ListView另一方面,似乎根本不关心这一点,只跟踪调查员的当前指数并简单地前进.
所以ListBox抛出异常,因为它跟踪修改,ListView但没有.
编辑:
ListBox.cs的SelectecObjectCollection的GetEnumerator方法如下:
public IEnumerator GetEnumerator() {
return InnerArray.GetEnumerator(SelectedObjectMask);
}
Run Code Online (Sandbox Code Playgroud)
并且ListView.cs's 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();
}
}
Run Code Online (Sandbox Code Playgroud)
所以它看起来像ListView返回一个数组的枚举器,它是常量,同时ListBox返回一个实际的枚举器作为其InnerArray项的过滤器.
我知道这不是你所问的; 但是在循环删除之前将所有项添加到临时列表总是有利的,因为你永远不知道枚举器是如何在后端实现的,也不知道它们将来如何改变.
| 归档时间: |
|
| 查看次数: |
1674 次 |
| 最近记录: |