为什么的foreach作品,同时去除ListView的项目,不会从列表框工作? [英] Why foreach works while removing items from ListView and doesn't work from ListBox?

查看:113
本文介绍了为什么的foreach作品,同时去除ListView的项目,不会从列表框工作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经开始学习C#和我有点困惑,我发现的行为。我揣摩,为什么在一个案件中,code是工作,在另一个没有:

I've started learning C# and I'm a bit confused about the behavior that I discovered. I try to figure out, why in one case the code is working and in another not:

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

第一个作品罚款,没有错误,但第二个抛出异常与集合被更改的信息。

First one works fine and there is no error, but the second one throws exception with information that the collection was changed.

谁能解释一下?

PS。在ListView控件的情况下,我在调试code和集合SelectedItems正在发生变化,但即使它运作良好。

PS. In case of ListView I was debugging code and collection SelectedItems was changing, but even though it worked well.

推荐答案

当我读了code里面.NET,更具体 ListBox.cs ListView.cs ,他们有保持他们的 SelectedItems 集合两个不同的类。

When I read the code inside .NET, more specifically ListBox.cs and ListView.cs, they have two different classes for keeping their SelectedItems collections.

ListBox.cs SelectedObjectCollection ,里面有这些成员:

ListBox.cs has SelectedObjectCollection, which has these members:

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

ListView.cs SelectedListViewItemCollection ,里面有这些成员只有:

ListView.cs has SelectedListViewItemCollection, which has these members only:

private ListView owner;
private int lastAccessedIndex = -1;

所以,通过观察,我想我可以推断出的ListBox 的收集是一个正确的枚举跟踪任何变化,而且在项目的数量列表。
的ListView ,在另一方面,似乎并不关心,在所有的,只有跟踪枚举当前指数,只是前进的脚步。

So by looking at that, I guess I can deduce that ListBox's collection is a proper enumerator that keeps track of any changes and the number of items that are in the list. ListView, on the other hand, seems to not care about that at all, and only keep track of the current index of the enumerator and simply steps forward.

所以的ListBox 抛出异常,因为它跟踪修改,的ListView 没有。​​

So ListBox throws the exception since it keeps track of modifications, ListView does not.

修改
ListBox.cs 取值的 SelectecObjectCollection 'GetEnumerator方法是这样的:

EDIT: ListBox.cs's SelectecObjectCollection's GetEnumerator method looks like this:

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

ListView.cs SelectedListViewItemCollection 的GetEnumerator方法是这样的:

And ListView.cs's SelectedListViewItemCollection's GetEnumerator method looks like this:

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 返回一个数组,这是不变的,而列表框的枚举返回一个实际枚举作为其项目的InnerArray的过滤器。

So it looks like ListView returns an enumerator of an array, which is constant, whilst ListBox returns an actual enumerator as a filter of its InnerArray of items.

我知道这是不是你问;但它始终是有利的,通过它循环删除的东西,因为之前所有的项目添加到一个临时目录,你可以的从不了解普查员是如何在后台执行,他们也将如何改变未来

I know this is not what you asked about; but it is always favorable to add all items to a temporary List before looping through it to remove things, since you can never know how the enumerators are implemented on the backend, nor how they might change in the future.

这篇关于为什么的foreach作品,同时去除ListView的项目,不会从列表框工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆