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 unter Verwendung CompareMem
durchführt.
Das ist in Ordnung für einen Datensatz voller Werttypen, ohne Polsterung. Aber ansonsten müssen Sie Ihre eigene Vergleichsfunktion angeben, wenn Sie die Liste instanziieren.
Wenn Sie die Details anzeigen möchten, ist der Standardvergleich für Datensätze in Generics.Defaults
implementiert. Für größere Datensätze ist der Gleichheitsvergleich diese Funktion:
function Equals_Binary(Inst: PSimpleInstance; const Left, Right): Boolean;
begin
Result := CompareMem(@Left, @Right, Inst^.Size);
end;
Für kleinere Aufzeichnungen gibt es eine Optimierung und Ihr Vergleich wird der 4-Byte-Vergleich sein. Das sieht wie folgt aus:
function Equals_I4(Inst: Pointer; const Left, Right: Integer): Boolean;
begin
Result := Left = Right;
end;
Das ist ein bisschen komisch, aber es interpretiert die 4 Bytes des Datensatzes als eine 4-Byte-Ganzzahl und führt integer Gleichheitsvergleich. Mit anderen Worten, das gleiche wie CompareMem
, aber effizienter.
Der Vergleich, den Sie verwenden möchten, könnte wie folgt aussehen:
TComparer<TSomeRecord>.Construct(
function const Left, Right: TSomeRecord): Integer
begin
Result := CompareStr(Left.Value, Right.Value);
end;
)
Verwenden CompareText
wenn Sie Groß- und Kleinschreibung wollen, und so weiter. Ich habe eine geordnete Vergleichsfunktion verwendet, weil das TList<T>
will.
Die Tatsache, dass der Standard-Datensatzvergleich ein Gleichheitsvergleich ist, sagt Ihnen, dass Versuche, Listen von Datensätzen ohne Angabe eines eigenen Vergleichs zu sortieren, zu unerwarteten Ergebnissen führen werden.
Da der Standardvergleich einen Gleichheitsvergleich verwendet sagt Ihnen, dass es nicht völlig unvernünftig wäre ein Vergleich wie folgt zu verwenden:
TComparer<TSomeRecord>.Construct(
function const Left, Right: TSomeRecord): Integer
begin
Result := ord(not (Left = Right));
end;
)
Das für ungeordnete Operationen wie IndexOf
oder Contains
in Ordnung sein, aber offensichtlich nicht Verwenden Sie überhaupt für Sortieren, binäre Suche und so weiter.
Wie funktioniert die Gleich Operator impl aussehen benutzen? Könnte mit http: // stackoverflow zusammenhängen.com/questions/8862807/list-and-contains-method –
Im Allgemeinen unterstützen Datensätze den Operator '=' nicht, und es ist nicht möglich, in Code zu erkennen, ob ein bestimmter Typ dies unterstützt. Daher muss die Standardimplementierung einen einfachen Speichervergleich verwenden für alle Arten, die es nicht * a priori * kennt. –
Dank @RobKennedy, dann wäre es nett, eine Gleichheitsbedingung für generische Typen zu haben, die die Existenz eines Gleichheitsoperators sicherstellen würde. – jpfollenius