Удаление элементов коллекции, через которую я проповедую - PullRequest
0 голосов
/ 03 августа 2011

Вот некоторый фиктивный код, который иллюстрирует то, что я хочу сделать:

List<int> list1 = new List<int>();
//Code to fill the list
foreach(int number in list1)
{
    if(number%5==0)
    {
        list1.Remove(number);
    }
}

Предполагая, что тест фактически удаляет int, он выдаст ошибку.Есть ли способ сделать это в foreach, или мне нужно преобразовать его в цикл for?

Ответы [ 6 ]

4 голосов
/ 03 августа 2011

Вы не можете удалить элементы из коллекции, для которой вы выполняете итерацию, для каждого. Я бы сделал это ...

list1 = list1.Where(l => l % 5 != 0).ToList();
2 голосов
/ 03 августа 2011

Метод RemoveAll () наиболее близок к тому, что вы хотите, я думаю:

list1.RemoveAll(i => i%5 == 0);
1 голос
/ 03 августа 2011

На самом деле, если вы хотите удалить список, как вы указали в ОП, вы можете сделать:

List<int> list1 = new List<int>();
//Code to fill the list
for(var n = 0; n < list.Count; i++)
{
    if (list[n] % 5 == 0)
    {
        list1.Remove(list[n--]);
    }
}

Отредактировано для добавления

Причина, по которой вы можетеНе изменяйте список в то время как для каждого цикла выглядит следующим образом:

[Serializable()] 
public struct Enumerator : IEnumerator<T>, System.Collections.IEnumerator
{
    private List<T> list;
    private int index; 
    private int version;
    private T current; 

    internal Enumerator(List<T> list) {
        this.list = list; 
        index = 0;
        version = list._version;
        current = default(T);
    } 

    public void Dispose() { 
    } 

    public bool MoveNext() { 

        List<T> localList = list;

        if (version == localList._version && ((uint)index < (uint)localList._size)) 
        {
            current = localList._items[index]; 
            index++; 
            return true;
        } 
        return MoveNextRare();
    }

    private bool MoveNextRare() 
    {
        if (version != list._version) { 
            ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EnumFailedVersion); 
        }

        index = list._size + 1;
        current = default(T);
        return false;
    } 

    public T Current { 
        get { 
            return current;
        } 
    }

    Object System.Collections.IEnumerator.Current {
        get { 
            if( index == 0 || index == list._size + 1) {
                 ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EnumOpCantHappen); 
            } 
            return Current;
        } 
    }

    void System.Collections.IEnumerator.Reset() {
        if (version != list._version) { 
            ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EnumFailedVersion);
        } 

        index = 0;
        current = default(T); 
    }

}
0 голосов
/ 03 августа 2011

Вы не можете изменить коллекцию, которую вы перечисляете, используя foreach. Что я часто делаю, так это использую цикл for и перебираю коллекцию в обратном направлении, поэтому вы можете безопасно удалять элементы, поскольку их длина не изменится, пока вы не перейдете к предыдущему элементу.

0 голосов
/ 03 августа 2011

Вы не можете сделать это на месте, используя foreach, потому что это делает счетчик недействительным.

Либо возьмите копию списка и выполните итерацию, либо используйте цикл другого типа, например цикл for ().

0 голосов
/ 03 августа 2011

Насколько я знаю, коллекция не может быть изменена в цикле foreach. Вам нужно изменить его на цикл for. Еще один способ добиться этого - использовать LINQ.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...