Wie ermittelt c # den Hashcode für ein Objekt?

Diese Frage ergibt sich aus der Diskussion überTupel.

Ich begann über den Hash-Code nachzudenken, den ein Tupel haben sollte. Was ist, wenn wir die KeyValuePair-Klasse als Tupel akzeptieren? Die GetHashCode () -Methode wird nicht überschrieben, daher werden wahrscheinlich die Hash-Codes der untergeordneten Elemente nicht berücksichtigt. Daher wird zur Laufzeit Object.GetHashCode () aufgerufen, das die nicht berücksichtigt reale Objektstruktur.

Dann können wir zwei Instanzen eines Referenztyps erstellen, die tatsächlich gleich sind, da GetHashCode () und Equals () überladen sind. Und benutze sie als "Kinder" in Tupeln, um das Wörterbuch "zu betrügen".

Aber es geht nicht! Die Laufzeit erkennt irgendwie die Struktur unseres Tupels und ruft den überladenen GetHashCode unserer Klasse auf!

Wie funktioniert es? Was ist die Analyse von Object.GetHashCode () gemacht?

Kann es die Leistung in einem schlechten Szenario beeinträchtigen, wenn wir einige komplizierte Schlüssel verwenden? (wahrscheinlich unmögliches Szenario ... aber immer noch)

Betrachten Sie diesen Code als Beispiel:

<code>namespace csharp_tricks
{
    class Program
    {
        class MyClass
        {
            int keyValue;
            int someInfo;

            public MyClass(int key, int info)
            {
                keyValue = key;
                someInfo = info;
            }

            public override bool Equals(object obj)
            {
                MyClass other = obj as MyClass;
                if (other == null) return false;

                return keyValue.Equals(other.keyValue);
            }

            public override int GetHashCode()
            {
                return keyValue.GetHashCode();
            }
        }

        static void Main(string[] args)
        {
            Dictionary<object, object> dict = new Dictionary<object, object>();

            dict.Add(new KeyValuePair<MyClass,object>(new MyClass(1, 1), 1), 1);

            //here we get the exception -- an item with the same key was already added
            //but how did it figure out the hash code?
            dict.Add(new KeyValuePair<MyClass,object>(new MyClass(1, 2), 1), 1); 

            return;
        }
    }
}
</code>

Aktualisieren Ich glaube, ich habe eine Erklärung dafür gefunden, wie unten in meiner Antwort angegeben. Die Hauptergebnisse davon sind:

Sei vorsichtig mit deinen Schlüsseln und ihren Hash-Codes :-)Bei komplizierten Wörterbuchschlüsseln müssen Sie Equals () und GetHashCode () korrekt überschreiben.

Antworten auf die Frage(6)

Ihre Antwort auf die Frage