Warum ist GetHashCode in der Objektklasse?

7

Warum GetHashCode ist Teil der Object-Klasse? Nur ein kleiner Teil der Objekte der Klassen wird als Schlüssel in Hash-Tabellen verwendet. Wäre es nicht besser, eine separate Schnittstelle zu haben, die implementiert werden muss, wenn Objekte der Klasse als Schlüssel in der Hash-Tabelle dienen sollen.

Es muss einen Grund geben, dass das MS-Team entschieden hat, diese Methode in die Object-Klasse aufzunehmen und sie "überall" verfügbar zu machen.

    
Incognito 22.06.2010, 18:31
quelle

7 Antworten

16

Es war ein Designfehler, der von Java kopiert wurde, IMO.

In meiner perfekten Welt:

  • ToString würde in ToDebugString umbenannt, um die Erwartungen entsprechend zu setzen
  • Equals und GetHashCode wären weg
  • Es würde eine ReferenceEqualityComparer Implementierung von IEqualityComparer<T> geben: Der Gleichheits-Teil ist im Moment einfach, aber es gibt keine Möglichkeit, einen "originalen" Hash-Code zu erhalten, wenn er überschrieben wird
  • Objekten würden keine Monitore zugeordnet sein: Monitor hätte einen Konstruktor und Enter / Exit etc wären Instanzmethoden.

Gleichheit (und damit Hashing) verursacht Probleme in Vererbungshierarchien im Allgemeinen - solange Sie immer die Art des Vergleichs angeben können, den Sie verwenden möchten (via IEqualityComparer<T> ) und Objekte können IEquatable<T> selbst implementieren, wenn sie möchten Ich sehe nicht, warum es auf Object sein sollte. EqualityComparer<T>.Default könnte die Referenzimplementierung verwenden, wenn T IEquatable<T> nicht implementiert hat und auf andere Objekte verschoben wird. Das Leben wäre angenehm.

Ah gut. Während ich dabei bin, war die Array-Kovarianz ein weiterer Plattformfehler. Wenn du Sprachfehler in C # willst, kann ich eine weitere kleine Ausrede beginnen, wenn du magst;) (Es ist immer noch meine Lieblingssprache, aber es gibt Dinge, die ich wünschte, ich hätte sie anders gemacht.)

Ich habe darüber anderswo gebloggt , BTW.

    
Jon Skeet 22.06.2010, 18:42
quelle
3
  

Nur ein kleiner Teil der Objekte der Klassen wird als Schlüssel in Hash-Tabellen verwendet

Ich würde behaupten, dass dies keine wahre Aussage ist. Viele Klassen werden oft als Schlüssel in Hashtabellen verwendet - und Objektverweise selbst werden sehr oft verwendet. Wenn die Standardimplementierung von GetHashCode in System.Object vorhanden ist, bedeutet dies, dass ein beliebiges Objekt ohne Einschränkungen als Schlüssel verwendet werden kann.

Dies scheint viel schöner zu sein, als eine benutzerdefinierte Schnittstelle für Objekte zu erzwingen, nur um sie hacken zu können. Sie wissen nie, wann Sie möglicherweise ein Objekt als Schlüssel in einer Hash-Sammlung verwenden müssen.

Dies gilt insbesondere, wenn Sie Dinge wie HashSet<T> verwenden. In diesem Fall wird oft eine Objektreferenz für die Verfolgung und Eindeutigkeit verwendet, nicht notwendigerweise als "Schlüssel". Hätte Hashing eine benutzerdefinierte Schnittstelle benötigt, würden viele Klassen weniger nützlich sein.

    
Reed Copsey 22.06.2010 18:37
quelle
1

Es erlaubt jedem Objekt, als "identity" Schlüssel verwendet zu werden. Dies ist in einigen Fällen vorteilhaft und in keinem schädlich. Also, warum nicht?

    
erickson 22.06.2010 18:37
quelle
0
  1. Also kann alles eingegeben werden. (Sorta)
  2. Auf diese Weise kann HashTable ein Objekt gegen etwas verwenden, das IHashable zum Beispiel implementiert.
  3. Um einen einfachen Gleichheitsvergleich durchzuführen.

Bei Objekten, die es nicht direkt implementieren, wird standardmäßig der interne Hash-Code von .NET verwendet, von dem ich glaube, dass er entweder eine eindeutige ID für die Objektinstanz oder ein Hash des Speicherabstands ist, den er belegt. (Ich kann mich nicht erinnern und .NET Reflektor kann nicht über die .NET-Komponente der Klasse gehen).

    
Aren 22.06.2010 18:36
quelle
0

GetHashCode befindet sich im Objekt, sodass Sie alles als Schlüssel in einer Hashtable, einer Basiscontainerklasse, verwenden können. Es bietet Symmetrie. Ich kann alles in eine ArrayList einfügen, warum nicht einen Hashtable?

Wenn Sie Klassen zum Implementieren von IHashable benötigen, dann schreiben Sie für jede versiegelte Klasse, die IHashable nicht implementiert, Adapter, wenn Sie sie als Schlüssel verwenden möchten, die die Hashing-Funktion enthalten. Stattdessen erhalten Sie es standardmäßig.

Auch Hashcodes sind eine gute zweite Zeile für den Vergleich der Objektgleichheit (erste Zeile ist Zeigergleichheit).

    
plinth 22.06.2010 18:37
quelle
0

Wenn jede Klasse GetHashCode hat, können Sie jedes Objekt in einen Hash setzen. Stellen Sie sich vor, Sie müssen Objekte von Drittanbietern verwenden (die Sie nicht ändern können) und diese in einen ab Hash setzen. Wenn diese Objekte dich nicht fiktiv IHashable implementiert haben, konntest du es nicht tun. Das ist offensichtlich eine schlechte Sache;)

    
Martin Thurau 22.06.2010 18:38
quelle
0

Nur eine Vermutung, aber der Garbage Collector kann Hash-Tabellen einiger Objekte intern speichern (vielleicht um verfolgbare Objekte zu verfolgen), was bedeutet, dass jedes Objekt einen Hash-Schlüssel haben muss.

    
munificent 23.06.2010 23:51
quelle

Tags und Links