Object.GetHashCode-Methode

Fungiert als Hashfunktion für einen bestimmten Typ. GetHashCode eignet sich für die Verwendung in Hashalgorithmen und Hashdatenstrukturen, z. B. in einer Hashtabelle.

Namespace: System
Assembly: mscorlib (in mscorlib.dll)

Syntax

'Declaration
Public Overridable Function GetHashCode As Integer
'Usage
Dim instance As Object
Dim returnValue As Integer

returnValue = instance.GetHashCode
public virtual int GetHashCode ()
public:
virtual int GetHashCode ()
public int GetHashCode ()
public function GetHashCode () : int

Rückgabewert

Ein Hashcode für das aktuelle Object.

Hinweise

Diese Methode kann von einer abgeleiteten Klasse überschrieben werden. Wertklassen müssen diese Methode überschreiben, um eine für diese Klasse geeignete Hashfunktion bereitzustellen, die eine bessere Verteilung in der Hashtabelle gewährleistet. Klassen, die als Schlüssel für eine Hashtabelle verwendet werden, müssen diese Methode ebenfalls überschreiben, da Objekte, die als Schlüssel für Hashtabellen verwendet werden, über diese Methode einen eigenen Hashcode generieren müssen. Wenn die als Schlüssel verwendeten Objekte keine nützliche Implementierung von GetHashCode bereitstellen, können Sie einen anderen Hashcodeanbieter auf Grundlage der System.Collections.IHashCodeProvider-Schnittstelle bereitstellen, wenn die Hashtable erstellt wird.

Die Standardimplementierung von GetHashCode garantiert weder Eindeutigkeit noch Konsistenz. Sie darf daher nicht als einziger Objektbezeichner für das Hashing verwendet werden. Abgeleitete Klassen müssen GetHashCode mit einer Implementierung überschreiben, die einen eindeutigen Hashcode zurückgibt. Die besten Ergebnisse werden erzielt, wenn der Hashcode auf dem Wert eines Instanzfelds oder einer Instanzeigenschaft und nicht auf dem Wert eines statischen Felds oder einer statischen Eigenschaft beruht.

Hinweise für Implementierer Eine Hashfunktion wird zum schnellen Generieren eine Zahl (Hashcode) verwendet, die dem Wert eines Objekts entspricht. Hashfunktionen sind i. d. R. für jeden Type spezifisch und müssen mindestens eines der Instanzfelder als Eingabe verwenden. Eine Hashfunktion muss folgende Eigenschaften aufweisen:

  • Wenn zwei Objekte desselben Typs denselben Wert darstellen, muss die Hashfunktion für beide Objekte denselben konstanten Wert zurückgeben.

  • Zu Optimierung der Leistung muss eine Hashfunktion eine Zufallsverteilung für alle möglichen Eingabewerte generieren.

  • Die Hashfunktion muss unabhängig von Änderungen des Objekts immer denselben Wert zurückgeben.

Die Implementierung von GetHashCode in der String-Klasse gibt z. B. für eindeutige Zeichenfolgenwerte eindeutige Hashcodes zurück. Daher geben zwei String-Objekte denselben Hashcode zurück, wenn sie denselben Zeichenfolgenwert darstellen. Darüber hinaus verwendet die Methode sämtliche Zeichen der Zeichenfolge, um eine verhältnismäßig zufällig verteilte Ausgabe zu erzielen, auch wenn die Eingabe auf bestimmte Zeichenbereiche beschränkt ist (z. B. wenn viele Benutzer nur Zeichenfolgen verwenden, die die unteren 128 ASCII-Zeichen enthalten, obwohl eine Zeichenfolge jedes der 65.535 Unicode-Zeichen enthalten könnte). GetHashCode muss immer denselben Wert für eine bestimmte Instanz des Objekts zurückgeben. Bei von Object abgeleiteten Klassen kann GetHashCode seine Aufgabe dann und nur dann an die Object.GetHashCode-Implementierung delegieren, wenn die abgeleitete Klasse Wertgleichheit als Verweisgleichheit definiert und der Typ kein Werttyp ist. Das Bereitstellen einer effizienten Hashfunktion für eine Klasse kann das Einfügen dieser Objekte in eine Hashtabelle erheblich beschleunigen. Bei einer Hashtabelle mit einer gut implementierten Hashfunktion wird die Suche nach einem Element in konstanter Zeit durchgeführt (eine O(1)-Operation). Bei einer Hashtabelle mit einer schlecht implementierten Hashfunktion hängt die Dauer der Suche von der Anzahl der Elemente in der Tabelle ab (sie ist z. B. eine O( n)-Operation, wobei n die Anzahl der Elemente in der Hashtabelle bezeichnet). Hashfunktionen müssen außerdem ohne viel Aufwand zu berechnen sein. Implementierungen von GetHashCode dürfen nicht zu zirkulären Verweisen führen. Wenn z. B. ClassA.GetHashCodeClassB.GetHashCode aufruft, darf ClassB.GetHashCode weder direkt noch indirekt ClassA.GetHashCode aufrufen. Implementierungen von GetHashCode dürfen keine Ausnahmen auslösen. Abgeleitete Klassen, die GetHashCode überschreiben, müssen außerdem Equals überschreiben, damit gewährleistet ist, dass zwei Objekte, die als gleich betrachtet werden, denselben Hashcode besitzen. Andernfalls könnte eine Hashtable falsche Ergebnisse liefern.

Beispiel

In einigen Fällen ist GetHashCode so implementiert, dass einfach ein ganzzahliger Wert zurückgegeben wird. Das folgende Beispiel veranschaulicht eine Implementierung von GetHashCode, bei der ein ganzzahliger Wert zurückgegeben wird.

using System;

public struct Int32 {
   public int value;

   //other methods...

   public override int GetHashCode() {
      return value;
   }
}
using namespace System;
public value struct Int32
{
public:
   int value;

   //other methods...
   virtual int GetHashCode() override
   {
      return value;
   }

};
import System.*;
public class Int32
{
    public int value;

    //other methods...
    public int GetHashCode()
    {
        return value;
    } //GetHashCode
} //Int32

Häufig besitzt ein Typ mehrere Datenfelder, die zur Generierung des Hashcodes beitragen können. Eine Möglichkeit, einen Hashcode zu generieren, besteht darin, diese Felder wie im folgenden Codebeispiel mit einer XOR (eXclusive OR)-Operation miteinander zu verknüpfen.

using System;

public struct Point {
   public int x;
   public int y; 

   //other methods
   
   public override int GetHashCode() {
      return x ^ y;
   }
}
using namespace System;
public value struct Point
{
public:
   int x;
   int y;

   //other methods
   virtual int GetHashCode() override
   {
      return x ^ y;
   }

};

Im folgenden Codebeispiel wird ein weiterer Fall veranschaulicht, in dem die Felder des Typs zur Generierung des Hashcodes mit XOR (eXclusive OR) verknüpft werden. Beachten Sie, dass in diesem Codebeispiel die Felder benutzerdefinierte Typen darstellen, von denen jeder GetHashCode und Equals implementiert.

using System;

public class SomeType {
   public override int GetHashCode() {
     return 0;
   }
}

public class AnotherType {
   public override int GetHashCode() {
     return 1;
   }
}

public class LastType {
   public override int GetHashCode() {
     return 2;
   }
}

public class MyClass {
   SomeType a = new SomeType();
   AnotherType b = new AnotherType();
   LastType c = new LastType();

   public override int GetHashCode () {
     return a.GetHashCode() ^ b.GetHashCode() ^ c.GetHashCode();
   }
}
using namespace System;
public ref class SomeType
{
public:
   virtual int GetHashCode() override
   {
      return 0;
   }

};

public ref class AnotherType
{
public:
   virtual int GetHashCode() override
   {
      return 1;
   }

};

public ref class LastType
{
public:
   virtual int GetHashCode() override
   {
      return 2;
   }

};

public ref class MyClass
{
private:
   SomeType^ a;
   AnotherType^ b;
   LastType^ c;

public:
   virtual int GetHashCode() override
   {
      return a->GetHashCode() ^ b->GetHashCode() ^ c->GetHashCode();
   }

};
import System;

public class SomeType {
   public override function GetHashCode(): int  {
     return 0;
   }
}

public class AnotherType {
   public override function GetHashCode(): int {
     return 1;
   }
}

public class LastType {
   public override function GetHashCode(): int {
     return 2;
   }
}

public class MyClass {
   var a: SomeType  = new SomeType();
   var b: AnotherType = new AnotherType();
   var c: LastType = new LastType();

   public override function GetHashCode () : int {
     return a.GetHashCode() ^ b.GetHashCode() ^ c.GetHashCode();
   }
}

Wenn der Datenmember einer abgeleiteten Klasse größer als Int32 ist, können die hohen und die niedrigen Bits des Werts mit einer XOR (eXclusive OR)-Operation verknüpft werden, wie im folgenden Codebeispiel gezeigt wird.

using System;

public struct Int64 {
   public long value;

   //other methods...

   public override int GetHashCode() {
      return ((int)value ^ (int)(value >> 32));
   }
}
using namespace System;
public value struct Int64
{
public:
   long value;

   //other methods...

   virtual int GetHashCode() override
   {
      return ((int)value ^ (int)(value >> 32));
   }
};
import System;

public class Int64 {
   var value : long;

   //other methods...

   public override function GetHashCode() : int {
      return (int(value) ^ int(value >> 32));
   }   
   
   function Int64(myValue : long) {
      value = myValue;
   }
}

Plattformen

Windows 98, Windows 2000 SP4, Windows CE, Windows Millennium Edition, Windows Mobile für Pocket PC, Windows Mobile für Smartphone, Windows Server 2003, Windows XP Media Center Edition, Windows XP Professional x64 Edition, Windows XP SP2, Windows XP Starter Edition

.NET Framework unterstützt nicht alle Versionen sämtlicher Plattformen. Eine Liste der unterstützten Versionen finden Sie unter Systemanforderungen.

Versionsinformationen

.NET Framework

Unterstützt in: 2.0, 1.1, 1.0

.NET Compact Framework

Unterstützt in: 2.0, 1.0

Siehe auch

Referenz

Object-Klasse
Object-Member
System-Namespace
Hashtable

Weitere Ressourcen

Hashtable-Auflistungstyp und Dictionary-Auflistungstyp