Когда я читаю код внутри .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;
Итак, глядя на это, я думаю, я могу вывести, что * 1016Коллекция * - это правильный перечислитель, который отслеживает любые изменения и количество элементов в списке.ListView
, с другой стороны, кажется, не заботится об этом вообще, а только следит за текущим индексом перечислителя и просто делает шаг вперед.
Так что ListBox
выдает исключение, поскольку оно сохраняетотслеживания изменений, ListView
нет.
РЕДАКТИРОВАТЬ : ListBox.cs
's SelectecObjectCollection
метод GetEnumerator выглядит следующим образом:
public IEnumerator GetEnumerator() {
return InnerArray.GetEnumerator(SelectedObjectMask);
}
ИМетод GetEnumerator ListView.cs
s SelectedListViewItemCollection
выглядит следующим образом:
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 элементов.
Я знаю, что это не то, о чем вы спрашивали;но всегда выгодно добавлять все элементы во временный список перед его циклическим перемещением, чтобы удалить объекты, поскольку вы не можете никогда знать, как реализованы перечислители в бэкэнде, и как они могут измениться в будущем.