c # collection.RemoveAll (collection.OfType <type>()); - PullRequest
4 голосов
/ 03 декабря 2011

Могу ли я сделать что-то вроде этого:

collection.RemoveAll(collection.OfType<type>());

Чтобы удалить все элементы данного типа из коллекции?

Ответы [ 4 ]

7 голосов
/ 03 декабря 2011

Оба из уже представленных ответов верны, но не приводим объяснение, почему пример кода автора не работает.Пара интересных моментов:

Во-первых, RemoveAll() не определен в интерфейсе ICollection или ICollection<T>;например, он определен в List<T>, но семантически эквивалентный метод в HashSet<T> называется RemoveWhere().Если вы хотите сделать это для любого ICollection<T>, вы должны написать метод расширения.

Во-вторых, пример кода вопроса передает последовательность элементов, которые должны быть удалены из коллекции, но List<T>.RemoveAll()и HashSet<T>.RemoveWhere() взять предикат для определения элементов, которые будут удалены (как показано в других ответах).Вы можете написать свой метод расширения, чтобы использовать другой подход, и передать IEnumerable<T>, как в вашем примере.Вы должны быть осторожны, потому что вы не можете сделать это:

foreach (var item in collection)
    if (ShouldRemove(item))
        collection.Remove(item);

Если вы попытаетесь это сделать, вы должны получить InvalidInvalidOperationException с сообщением типа «Коллекция была изменена; операция перечисления может не выполнятьсявыполнить. "

4 голосов
/ 03 декабря 2011

Если я правильно понимаю, у вас есть одна коллекция объектов любого типа, и вы хотите удалить все элементы типа из этой коллекции. Если это так, то все просто:

objects.RemoveAll(q=>q.GetType()==typeof(YourType));
2 голосов
/ 15 сентября 2016

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

ICollection collection = GetCollection();
foreach (object obj in collection.Where(obj => obj is type).ToList())
     collection.Remove(obj);

Вы можете завершить перечисление, вызвав ToList, чтобы удаление было разрешено снова. Это абсолютно неэффективно, так как для получения объектов требуется одно перечисление, а затем удаляет их один за другим, возможно, каждый раз требуя перечисления. Если тип используемой вами коллекции имеет свои собственные методы, такие как List.RemoveAll, используйте их вместо этого, но использование «коллекции» подразумевает, что вы не знаете ее тип.

В качестве альтернативы, если важность не в сохранении объекта, рассмотрите возможность переназначения:

collection = collection.Where(obj => obj is type == false).ToList();
2 голосов
/ 03 декабря 2011

Я бы сделал что-то вроде этого:

collection.RemoveAll (i => collection.OfType (). Contains (i)); <Ч /> EDIT:

 collection.RemoveAll(i => i is type);
...