Какой самый простой способ получить доступ через List <T>для удаления нежелательных объектов? - PullRequest
8 голосов
/ 13 июля 2009

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

Однако следующий код получает ошибку недопустимая операция во второй итерации, поскольку сама _collection была изменена:

foreach (User user in _collection)
{
    if (!user.IsApproved())
    {
        _collection.Remove(user);
    }
}

Я мог бы создать другую коллекцию List и копировать их туда-сюда, но тогда у меня возникнет проблема не клонированных ссылочных типов и т. Д.

Есть ли способ выполнить вышесказанное более элегантно, чем копировать _collection в другую переменную List?

Ответы [ 3 ]

54 голосов
/ 13 июля 2009
_collection.RemoveAll(user => !user.IsApproved());

Если вы все еще на 2.0:

_collection.RemoveAll(delegate(User u) { return !u.IsApproved(); });

Кстати, если вы не хотите прикасаться к исходному списку, вы можете получить другой список разрешенных пользователей с:

_collection.FindAll(user => user.IsApproved());
4 голосов
/ 13 июля 2009

Вы всегда можете начать с верхнего индекса и переходить к 0:

for (int i = _collection.Count - 1; i >= 0; i--)
{
    User user = _collection[i];
    if (!user.IsApproved())
    {
        _collection.RemoveAt(i);
    }
}

Ответ Мехрдада выглядит чертовски элегантно.

0 голосов
/ 19 июля 2009

Всякий раз, когда есть вероятность, что коллекция будет изменена в цикле, выберите вместо нее цикл for. Решение, данное Mehrdad, прекрасно и определенно стоит попробовать!

Вот код, который я считаю полезным при работе с изменяемыми коллекциями:

for(int index=0;index < _collection.Count; index++)
{
    if (!_collection[index].IsApproved)
    {
        _collection.RemoveAt(index);
        index--;
    }
}
...