как я могу использовать метод foreach вместо метода for с удалением метода списка?
Вопрос
Как я могу использовать второй метод вместо первый?
первый (веб-контроль пользователя)
public void Remove()
{
int count = this.ListBox1.Items.Count;
for (int i = count - 1; i > -1; i--)
{
if (ListBox1.Items[i].Selected)
{
ListBox1.Items.Remove(ListBox1.Items[i]);
}
}
}
Test.aspx (первый тест)
protected void btnRemove_Click(object sender, EventArgs e)
{
ItemOrderer2.Remove();
}
второй (управление веб-пользователем)
public void Remove(string value)
{
ListItem li = new ListItem();
li = ListBox1.Items.FindByValue(value);
if (li != null)
{
this.ListBox1.Items.Remove(li);
}
Test.aspx(тест секунды)
protected void btnRemove_Click(object sender, EventArgs e)
{
// ItemOrderer2.Remove();
if (ItemOrderer2.Items.Count > 0)
foreach (ListItem li in ItemOrderer2.Items)
{
if (li.Selected)
{
ItemOrderer2.Remove(li.Value);
}
}
}
Решение
Вы не можете использовать foreach
если вы удаляете данные внутри foreach
- это (намеренно) ломает итератор.
Если for
работает, зачем менять?Если ты отчаянный использовать foreach
, затем постройте отдельный сначала перечислите - например:
List<ListItem> remove = new List<ListItem>();
foreach(ListItem li in ItemOrdere2.Items) {
if(li.Selected) remove.Add(li);
}
foreach(ListItem li in remove) {
ItemOrderer2.Remove(li); // or similar
}
Первый запрос часто можно упростить с помощью LINQ, если он доступен.
Другие советы
Вы можете сначала записать значения, которые нужно удалить, в список, а затем запустить их с помощью функции удаления.При необходимости это можно улучшить.
var removedValues = ItemOrderer2.Items
.Where(li => li.Selected)
.Select(li => li.Value).ToList();
foreach (var removedValue in removedValues) {
ItemOrderer2.Remove(removedValue);
}
Вы не можете изменить коллекцию, которую выполняете в цикле foreach.
При этом кажется, что вы пытаетесь удалить выбранные элементы из ListBox.Вы также можете использовать что-то вроде:
while(ItemOrderer2.SelectedItem != null)
{
ItemOrderer2.Items.Remove(ItemOrderer2.SelectedItem);
}
Что ж, вы не можете вносить какие-либо изменения в IList<> с помощью foreach просто потому, что это изменит количество элементов в нем.
Кроме того, первый метод, который вы показали, ошибочен, поскольку счетчик может начинаться с 20, но если вы удалите 10 элементов с помощью своего метода, счетчик все равно будет 20, и вы выйдете за пределы IList<>
По сути, если вы хотите удалить/добавить что-то во время итерации, вам нужно сделать что-то вроде
for (int i = 0; i < ListBox1.Items.Count; i++)
{
if (ListBox1.Items[i].Selected)
{
ListBox1.Items.RemoveAt(i)
i--;
}
}
Обратите внимание на i--, если вы что-то удалите.Допустим, выбран элемент [2], ваш цикл будет выглядеть следующим образом:
- если количество > 0, продолжить
- если выбран элемент [0], удалите его (это не так)
- увеличить наш счетчик
- если количество > 1, продолжить
- если выбран элемент [1], удалите его (это не так)
- увеличить наш счетчик
- если количество > 2, продолжить
- элемент[2] выбран, удалите его (он есть)
- удалить элемент[2] (теперь то, что раньше было элементом[3], станет элементом[2]
- уменьшить наш счетчик
- увеличить наш счетчик
- если количество > 2, продолжить
- ...
Надеюсь это поможет :)