Anormales Verhalten der LINQ Distinct()-Methode in benutzerdefinierten Objekten
Bei Verwendung von LINQ to Objects führt die Methode Distinct()
möglicherweise nicht immer zu den erwarteten Ergebnissen, wenn mit benutzerdefinierten Objekten gearbeitet wird. Standardmäßig berücksichtigt LINQ nur Referenzen für Eindeutigkeitsvergleiche.
Im bereitgestellten Codebeispiel haben Sie eine Liste von Book
-Objekten, von denen jedes eine Liste von Author
-Objekten enthält. Wenn Sie SelectMany()
verwenden, um die Authors
-Sammlung in eine einzelne Liste zu reduzieren, und dann Distinct()
aufrufen, erwarten Sie, dass nur der eindeutige Autor zurückgegeben wird. Sie stellen jedoch fest, dass derselbe Autor (Jon Skeet) zweimal vorkommt.
Das Problem besteht darin, dass die Distinct()
-Methoden in LINQ standardmäßig mit Objektreferenzen arbeiten. Da Ihre Liste zwei separate Author
-Objekte enthält, betrachtet LINQ sie als unterschiedlich, obwohl sie denselben Wert haben. Um dieses Problem zu lösen, müssen Sie eine benutzerdefinierte Gleichheitsimplementierung bereitstellen, die klar definiert, wie Objekte auf Eindeutigkeit verglichen werden.
Überschreiben Sie die Equals-Methode
Wie in Ihrer Frage vorgeschlagen, können Sie die Methode Author
in der Klasse Equals()
überschreiben, um Gleichheitsbedingungen anzugeben. Ihre aktuelle Implementierung gibt jedoch immer true
zurück, sodass alle Autoren gleich erscheinen.
IEquatable-Schnittstelle implementieren
Ein geeigneterer Ansatz besteht darin, die IEquatable<Author>
-Schnittstelle in Ihrer Klasse zu implementieren. Über diese Schnittstelle können Sie benutzerdefinierte Gleichheitskomparatoren definieren. In Ihrem Fall können Sie anhand des Autorennamens vergleichen:
public class Author : IEquatable<Author> { public bool Equals(Author other) { return FirstName == other.FirstName && LastName == other.LastName; } }
Autor in LINQ-Abfragen wiederverwenden
Nach der Implementierung von IEquatable<Author>
können Sie damit das Verhalten der Methode Distinct()
verbessern. Ändern Sie Ihre LINQ-Abfrage wie folgt:
var temp = books.SelectMany(book => book.Authors).DistinctBy(a => new { a.FirstName, a.LastName });
Durch die Definition von Tupeln von DistinctBy()
und FirstName
mithilfe von LastName
und einem benutzerdefinierten Lambda-Ausdruck können Sie explizit angeben, wie Autoren auf Einzigartigkeit verglichen werden.
Indem Sie diese Schritte befolgen, können Sie sicherstellen, dass die Distinct()
-Methode doppelte Autoren korrekt identifiziert und eliminiert und gleichzeitig ihre Werte beibehält.
Das obige ist der detaillierte Inhalt vonWarum funktioniert LINQ Distinct() mit benutzerdefinierten Objekten nicht wie erwartet?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!