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.
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 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 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.
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.
HashTable
ein Objekt gegen etwas verwenden, das IHashable
zum Beispiel implementiert. 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).
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).
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;)
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.
Tags und Links language-agnostic .net c# clr