45 votes

Suppression des éléments de IEnumerable<T>

J'ai 2 collections IEnumerable.

IEnumerable<MyClass> objectsToExcept 

et

IEnumerable<MyClass> allObjects.

objectsToExcept peut contenir des objets de allObjects .

J'ai besoin d'enlever de allObjects objets dans objectsToExcept . Par exemple :

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

Ou

allObject.Except(objectsToExcept)

Mais ça ne marche pas. Le compte après l'exécution des méthodes indique qu'aucun élément n'a été retiré.

58voto

Jon Skeet Points 692016

Je ne vois pas comment la première version pourrait compiler, et la deuxième version ne fera rien à moins que vous n'utilisiez le résultat. Elle ne supprime rien de la collection existante - en fait, il se peut même qu'il n'y ait pas d'éléments de la collection. être une collection en mémoire la soutenant. Elle renvoie simplement une séquence qui, lorsqu'elle est itérée, renvoie les valeurs appropriées.

Si vous sont en utilisant le résultat, par exemple

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

alors tout devrait bien se passer si vous avez remplacé GetHashCode y Equals o si vous êtes heureux d'utiliser l'égalité de référence. Essayez-vous de supprimer les valeurs logiquement égales, ou faites-vous la même chose que les autres ? références se produisent dans les deux séquences ? Avez-vous remplacé GetHashCode y Equals et si oui, êtes-vous sûr que ces implémentations fonctionnent ?

En principe, tout devrait bien se passer - je vous suggère d'essayer de créer un programme court mais complet qui démontre le problème ; je pense qu'en le faisant, vous découvrirez ce qui ne va pas.

29voto

Thomas Levesque Points 141081

Il n'y a pas Remove méthode sur IEnumerable<T> car il n'est pas censé être modifiable.

El Except ne modifie pas la collection originale : elle retourne une nouvelle collection qui ne contient pas les éléments exclus :

var notExcluded = allObjects.Except(objectsToExcept);

16voto

Mike Two Points 16706

Remove et Except ne modifient pas l'IEnumerable original. Elles en retournent un nouveau.

var result = allObject.Except(objectsToexcept);

4voto

lordcheeto Points 629

Alors que les autres réponses sont correctes, je dois ajouter que le résultat de la Except() peut être réaffecté à la variable d'origine. C'est-à-dire,

allObjects = allObjects.Except(objectsToExcept);

Gardez également à l'esprit que Except() produira la différence d'ensemble des deux collections, donc s'il y a des doublons des variables à supprimer, ils seront tous supprimés.

0voto

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X