Distinct () ruft nicht gleich Methoden auf

8

Ich habe IEqualityComparer und IEquatable implementiert (beides nur um sicher zu sein), aber wenn ich die Distinct () -Methode für eine Collection aufruft, ruft sie nicht die Methoden auf, die mit ihr geliefert werden. Hier ist der Code, den ich ausführe, wenn ich Distinct () aufruft.

%Vor%

Ich möchte eine ObservableCollection zurückgeben, die keine doppelten Objekte enthält, die sich in der ObservableCollection von Gigs befinden.

Ich implementiere die Schnittstellen wie folgt in der GigViewModel-Klasse:

%Vor%

Und überschreiben Sie die Methoden, die mit den Schnittstellen kommen:

%Vor%

Danke für die Hilfe, die ich bekomme. Also habe ich eine separate Klasse erstellt, die IEqualityComparer implementiert und ihre Instanz an die disctinct-Methode übergeben hat. Aber die Methoden werden immer noch nicht ausgelöst.

EqualityComparer:

%Vor%

Der Aufruf Distinct() :

%Vor%

EDIT2:

Die Methode GetHashCode() wird aufgerufen! Nach der Implementierung der neuen Klasse. Aber die Sammlung enthält immer noch Duplikate. Ich habe eine Liste von 'Gigs', die ein 'Artiest' (oder Künstler) Objekt enthalten. Dieser Künstler hat eine Naam-Eigenschaft, die eine Zeichenfolge (Name) ist.

    
Tim Kranen 07.01.2014, 14:30
quelle

2 Antworten

6

Sie haben also das Objekt, das selbst verglichen wird, sowohl IEquatable als auch IEqualityComparer implementieren. Das macht im Allgemeinen keinen Sinn. IEquatable ist eine Art zu sagen, dass ein Objekt sich mit etwas anderem vergleichen kann. IEqualityComparer ist eine Art zu sagen, dass es zwei verschiedene Dinge vergleichen kann, die Sie einander geben. Im Allgemeinen willst du das eine oder das andere, nicht beides.

Wenn Sie IEquatable implementieren möchten, muss das Objekt nicht nur eine Equals -Methode der entsprechenden Signatur haben, sondern muss GetHashCode überschreiben, um eine sinnvolle Implementierung für die gegebene Definition der Gleichheit zu haben. Das hast du nicht gemacht . Sie haben die Methode GetHashCode erstellt, die ein Objekt als Parameter akzeptiert, aber das ist die Überladung, die für IEqualityComparer verwendet wird. Sie müssen die parameterlose Version überschreiben, wenn Sie IEquatable verwenden (die in Object definierte).

Wenn Sie eine Klasse erstellen möchten, die IEqualityComparer implementiert, müssen Sie den Vergleich an die Methode Distinct übergeben. Da Sie das Objekt als eigenen Vergleich definiert haben, müssen Sie eine Instanz dieses Objekts als zweiten Parameter übergeben. Natürlich macht das auf diese Weise nicht wirklich viel Sinn; Es wäre also besser, wenn Sie diesen Weg gehen, die beiden Methoden, die zu IEqualityComparer gehören, in einen neuen Typ zu übernehmen und eine Instanz dieses Typs für die Methode Distinct zu erstellen. Wenn Sie tatsächlich ein Objekt mit diesen Definitionen als Vergleich übergeben haben, würde es gut funktionieren.

    
Servy 07.01.2014, 15:27
quelle
1

Wenn Sie MSDNs Ratschläge befolgen, sind Sie der Beste Aus dem Erstellen einer separaten Klasse für Ihre Gleichheitsvergleiche:

  

Wir empfehlen, dass Sie von der EqualityComparer-Klasse ableiten   anstatt die Schnittstelle IEqualityComparer zu implementieren, weil   Die EqualityComparer-Klasse testet auf Gleichheit mit dem   IEquatable.Equals-Methode anstelle der Object.Equals-Methode. Dies   stimmt mit Contains, IndexOf, LastIndexOf und Remove überein   Methoden der Dictionary-Klasse und andere generische   Sammlungen.

Erstellen Sie also eine Klasse, GigViewModelComparer , die von EqualityComparer abgeleitet ist, und stellen Sie Ihre Methoden Equals und GetHashCode dort ein.

Geben Sie dann eine Instanz dieser neuen Vergleichsklasse in Ihrem Aufruf an Gigs.Distinct(new GigViewModelComparer()) ein und es sollte funktionieren. Folgen Sie in dem Beispiel in dem MSDN-Link, den ich oben bereitstellte.

Ich habe noch nie jemanden gesehen, der IEqualityComparer in der gleichen Klasse wie die Art von Objekten implementiert, die die fragliche Sammlung enthält, das ist wahrscheinlich zumindest ein Teil Ihres Problems.

    
Sven Grosen 07.01.2014 14:56
quelle