2016-12-10 4 views
4

Für ein Delphi-Projekt (mit RAD Studio XE7 erstellt) möchte ich ein Wörterbuch mit Pinseln erstellen. Jedes Wörterbuchelement enthält ein TMyBrush-Objekt als Schlüssel, das den abzurufenden Pinsel und einen GDI + -Pinsel als Wert beschreibt.GetHashCode gute Praxis?

TMyBrush Die Klasse enthält 3 Felder

  • ein Aufzählungstyp, die Art der Bürste (fest, Gradient, ...)
  • A TBrushInfo Klasse, beschreibt die Bürste Gehalt (Farbe, Wickelmodus zu bestimmen , ...)
  • A TRect, dass ein Klemmfeld

In meinem Wörterbuch steht, möchte ich auf seine Eigenschaften basieren, und nicht auf seinem Beispiel einen Pinsel abzurufen. Ich möchte beispielsweise einen schwarzen Solid-Pinsel aus meinem Wörterbuch erhalten, indem ich eine lokale TMyBrush-Instanz erstelle, sie zu einem schwarzen Vollton konfiguriere und den passenden GDI + -Wert mithilfe der TryGetValue() - Funktion erhalte. Dafür habe ich einen TMyBrushComparer erstellt.

Schreiben der Equals() -Funktion ist kein Problem für mich. Ich weiß jedoch nicht, was die beste Methode ist, um die GetHashCode() - Funktion zu schreiben. Ich würde dazu neigen, eine Funktion wie folgt zu schreiben:

function TMyBrushComparer.GetHashCode(const pValue: TMyBrush): Integer; 
begin 
    Result := BobJenkinsHash(pValue, SizeOf(TMyBrush), 0); 
end; 

aber ich glaube, dass ist nicht eine sehr gute Praxis, es ist richtig? Also, was ist die beste Vorgehensweise, um eine gute GetHashCode() - Funktion für meinen TMyBrushComparer zu schreiben?

Grüße

Antwort

3

Der Code in der Frage Hashes die Adresse des Objekts, anstatt seinen Wert und so ist mit der Definition der Gleichheit nicht konsistent.

Ihre Definition der Gleichheit ist, dass drei der Felder gleich sind. Ihre Hash-Funktion sollte dieser Definition entsprechen. Hash jedes der drei Felder und kombinieren Sie die Werte, zum Beispiel mit dem hier skizzierten Ansatz: https://stackoverflow.com/a/263416/505088

Zwei Ihrer Felder sind Werttypen. Sie sind einfach zu hashen, um Wertidentität zu entsprechen. Das Pinselinfo-Feld scheint ein Referenztyp zu sein. Also müssen Sie wieder entscheiden, welche Form der Identität Sie wollen (Referenzidentität, Wertidentität oder vielleicht etwas anderes) und dann passenden Gleichheitstest und Hash implementieren.