Подтвердить что ты не робот

Удалить элементы из IEnumerable <T>

У меня есть 2 коллекции IEnumerable.

IEnumerable<MyClass> objectsToExcept 

и

IEnumerable<MyClass> allObjects.

objectsToExcept может содержать объекты из allObjects.

Мне нужно удалить из allObjects объектов в objectsToExcept. Например:

foreach (var myClass in objectsToExcept)
{
allObjects.Remove(myClass);
}

или

allObject.Except(objectsToExcept)

Но это не сработает. Счетчик после выполнения методов указывает, что элементы не были удалены.

4b9b3361

Ответ 1

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

Если вы используете результат, например

IEnumerable<MyClass> others = allObjects.Except(objectsToExcept);
foreach (MyClass x in others)
{
    ...
}

тогда это должно быть хорошо, если вы переопределили GetHashCode и Equals, или если вы счастливы использовать ссылочное равенство. Вы пытаетесь удалить логически равные значения или делать одни и те же ссылки в обеих последовательностях? Вы переопределили GetHashCode и Equals, и если да, уверены ли вы, что эти реализации работают?

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

Ответ 2

В IEnumerable<T> нет метода Remove, поскольку он не предназначен для модификации.

Метод Except не изменяет исходную коллекцию: он возвращает новую коллекцию, которая не содержит исключенных элементов:

var notExcluded = allObjects.Except(objectsToExcept);

См. Except на MSDN.

Ответ 3

Удалить и не изменять оригинальный IEnumerable. Они возвращают новый. попробуйте

var result = allObject.Except(objectsToexcept);

Ответ 4

В то время как другие ответы верны, я должен добавить, что результат вызова Except() можно вернуть обратно к исходной переменной. То есть

allObjects = allObjects.Except(objectsToExcept);

Также имейте в виду, что Except() создаст заданную разницу между двумя коллекциями, поэтому, если есть дубликаты переменных, которые нужно удалить, все они будут удалены.

Ответ 5

others.Where(contract => !objectsToExcept.Any()).ToList();