Zeichne Gleichheit in generischen Sammlungen auf

8

Angenommen, Sie haben einen Datensatz mit einem überladenen Gleichheitsoperator

%Vor%

(Implementierung vergleicht String-Werte). Wenn zwei Datensätze zu der Liste hinzugefügt werden, die basierend auf dem überladenen Operator gleich sind, würde ich erwarten, dass die Methode Contains in beiden Fällen true zurückgibt. Aber in der Tat scheint die generische Liste nur den Speicherinhalt von Datensätzen zu vergleichen, anstatt den überladenen Gleichheitsoperator anzuwenden.

%Vor%

Ist das das erwartete Verhalten? Irgendwelche Erklärungen?

    
jpfollenius 04.06.2013, 14:30
quelle

2 Antworten

8

Angenommen, Sie haben im Konstruktor keinen Vergleich zu TList.Create angegeben, erhalten Sie TComparer<TSomeRecord>.Default als Vergleich. Und das ist ein Vergleich, der einen einfachen binären Vergleich mit CompareMem durchführt.

Das ist in Ordnung für einen Datensatz voller Werttypen ohne Auffüllung. Aber ansonsten müssen Sie beim Instanziieren der Liste Ihre eigene Vergleichsfunktion angeben.

Wenn Sie sich die Details ansehen möchten, wird der Standardvergleich für Datensätze in Generics.Defaults implementiert. Für größere Datensätze ist der Gleichheitsvergleich diese Funktion:

%Vor%

Für kleinere Datensätze gibt es eine Optimierung und Ihr Vergleicher ist der 4-Byte-Vergleicher. Das sieht so aus:

%Vor%

Das ist ein bisschen seltsam, aber es interpretiert die 4 Bytes Ihres Datensatzes als eine 4-Byte-Ganzzahl und führt einen ganzzahligen Gleichheitsvergleich durch. Mit anderen Worten, das gleiche wie CompareMem , aber effizienter.

Der Vergleich, den Sie verwenden möchten, könnte wie folgt aussehen:

%Vor%

Verwenden Sie CompareText , wenn Groß- und Kleinschreibung nicht beachtet werden soll. Ich habe eine geordnete Vergleichsfunktion verwendet, weil% TList<T> dies wünscht.

Die Tatsache, dass der Standard-Datensatzvergleich ein Gleichheitsvergleich ist, sagt Ihnen, dass Versuche, Listen von Datensätzen zu sortieren, ohne einen eigenen Vergleicher anzugeben, zu unerwarteten Ergebnissen führen werden.

Da der Standardvergleich einen Gleichheitsvergleich verwendet, wird Ihnen gesagt, dass es nicht völlig unvernünftig wäre, einen Vergleich wie diesen zu verwenden:

%Vor%

Das ist gut für ungeordnete Operationen wie IndexOf oder Contains , aber offensichtlich keine Verwendung für Sortieren, binäre Suche und so weiter.

    
David Heffernan 04.06.2013, 14:43
quelle
3

Um das erwartete Verhalten zu erhalten, müssen Sie die Liste mit einem Vergleich erstellen.

In diesem Fall sollten Sie

verwenden %Vor%     
Sir Rufo 04.06.2013 14:50
quelle