List.Except funktioniert nicht

8

Ich versuche 2 Listen wie unten zu subtrahieren, assignUsers hat 3 Datensätze und assignedUsers hat 2 Zeilen. Nach Except method bekomme ich noch 3 Zeilen, obwohl ich 1 Datensatz bekommen sollte, weil 2 Zeilen in assignedUsers ähnlich zu assignUsers

sind %Vor%     
Ehsan Davoudi 20.10.2012, 12:00
quelle

2 Antworten

25

Damit Except method wie erwartet funktioniert, muss die Klasse AssignUserViewModel die Methoden GetHashCode und Equals korrekt überschreiben.

Wenn beispielsweise AssignUserViewModel -Objekte durch ihre Id eindeutig definiert sind, sollten Sie die Klasse folgendermaßen definieren:

%Vor%

Andernfalls können Sie, wenn Sie die Klassenimplementierung nicht ändern können / wollen, ein IEqualityComparer<> implementieren und es an die Methode Except übergeben, z. :

%Vor%

dann würde deine letzte Zeile werden:

%Vor%     
digEmAll 20.10.2012, 12:14
quelle
2

Warum passiert das? Wenn Sie Operationen setzen (Unterschiedlich, außer, Schnittmenge, Union) verwenden, müssen Sie die Sequenz vergleichen ( s) Elemente für die Gleichheit. Standardmäßig verwendet Linq Object.Equals und Object.GetHashCode Methoden zum Vergleichen von Elementen. Wenn diese Methoden in Ihrem Typ nicht überschrieben werden, wird die Implementierung der Basisklasse verwendet, die Objekte anhand der Referenzgleichheit vergleicht. Die Standardimplementierung garantiert, dass zwei Objekte, die die gleiche Referenz haben, denselben Hash-Code haben (also als gleichwertig betrachtet werden). Das ist dein Fall. Mapper class erstellt neue Instanzen von AssignUserViewModel -Objekten, die unterschiedliche Referenzen haben und nicht als gleich behandelt werden können (auch wenn alle Feldwerte gleich sind).

Also, was könnten wir damit machen?

  • Überschreiben Sie die Methoden Equals und GetHashCode in Ihrer Klasse. Es liegt an Ihnen, wie Sie die Gleichheit der Objekte behandeln - alle Felder oder nur die Identität. Linq verwendet Ihre Methoden zum Vergleichen von Elementen.

  • Geben Sie Ihren eigenen Vergleicher an (dies ist in der Regel der Fall, wenn Sie Ihr Objekt nicht ändern und Equals und GetHashCode überschreiben können. Ja, alle Linq-Set-Operationen haben zwei Überladungen - eine verwendet Standardkomparator und andere, welches deine akzeptiert IEqualityComparer<T> .

  • Verwenden Sie anonyme Typen. Alle anonymen Typen haben bereits die Methoden Equals und GetHashCode generiert, die einen Vergleich aller Eigenschaften verwenden, um festzustellen, ob Objekte gleich sind. In diesem Fall müssen Sie weder Ihren Typ ändern noch einen Vergleicher erstellen.

Sie haben also bereits Beispiele für die ersten zwei Ansätze, hier ist der letzte:

%Vor%     
Sergey Berezovskiy 20.10.2012 12:55
quelle

Tags und Links