Dieser Artikel wurde maschinell übersetzt. Wenn Sie die englische Version des Artikels anzeigen möchten, aktivieren Sie das Kontrollkästchen Englisch. Sie können den englischen Text auch in einem Popupfenster anzeigen, indem Sie den Mauszeiger über den Text bewegen.
Übersetzung
Englisch

Object.GetHashCode-Methode: ()

 

Veröffentlicht: Oktober 2016

Fungiert als die Standardhashfunktion.

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

Public Overridable Function GetHashCode As Integer

Rückgabewert

Type: System.Int32

Ein Hashcode für das aktuelle Objekt.

Ein Hashcode ist ein numerischer Wert, der verwendet wird, zum Einfügen und identifizieren z. B. ein Objekt in einer Auflistung hashbasierten der Dictionary(Of TKey, TValue) -Klasse, die Hashtable Klasse oder einen Typ abgeleitet wurde. die DictionaryBase Klasse. Die GetHashCode Methode bietet diese Hashcode für Algorithmen, die schnelle Überprüfung der Objektgleichheit benötigen.

System_CAPS_noteHinweis

Informationen zur Verwendung von Hashcodes in Hashtabellen sowie einige zusätzliche Code Hashalgorithmen finden Sie unter der Hash Function Eintrag in Wikipedia.

Zwei Objekte, die gleich sind, geben denselben Hashcode zurück. Das Gegenteil stimmt aber nicht "true": gleich Hashcodes implizieren keine Objektgleichheit, da verschiedene (ungleich) Objekte identische Hashcodes verfügen können. .NET Framework gewährleistet zudem nicht die standardmäßige Implementierung des der GetHashCode -Methode, und der Wert, der diese Methode gibt unterschiedlich ausfallen, zwischen .NET Framework-Versionen und Plattformen, wie z. B. 32-Bit und 64-Bit-Plattformen. Aus diesen Gründen verwenden Sie nicht die standardmäßige Implementierung dieser Methode als eine eindeutige Objekt-ID für hashing Zwecke. Führen Sie die zwei Konsequenzen aus diesem:

  • Sie sollten nicht davon ausgehen, dass gleich Hashcodes Objektgleichheit hinweisen.

  • Sie sollten nie beibehalten oder einen Hashcode außerhalb der Anwendungsdomäne, in der es erstellt wurde, verwenden, da das gleiche Objekt zwischen Anwendungsdomänen, Prozessen und Plattformen hash kann.

System_CAPS_warningWarnung

Ein Hash ist für effizientes Einfügen und Suchen in den Auflistungen vorgesehen, die auf einer Hashtabelle basieren. Ein Hashcode ist kein permanente Wert. Aus diesem Grund:

  • Serialisieren Sie weder hashcodierte Darstellungen noch speichern Sie sie in den Datenbanken.

  • Verwenden Sie nicht den Hash als Schlüssel an, um ein Objekt aus einer schlüsselgebundenen Auflistung abzurufen.

  • Senden Sie Hashcodes nicht anwendungsdomänen- oder prozessübergreifend. In einigen Fällen können der Hashcodes pro Domäne pro Prozess oder pro Anwendung berechnet werden.

  • Verwenden Sie nicht den Hashcode, statt eines Werts von einer kryptografischen Hashfunktion zurückgegeben, wenn Sie einen kryptografisch starken Hash benötigen. Verwenden Sie für kryptografische Hashes eine abgeleitete Klasse die System.Security.Cryptography.HashAlgorithm oder System.Security.Cryptography.KeyedHashAlgorithm Klasse.

  • Testen Sie nicht auf die Gleichheit von Hashcodes, um zu bestimmen, ob zwei Objekte gleich sind. (Ungleich Objekte können identische Hashcodes verfügen.) Um auf Gleichheit zu testen, rufen Sie die ReferenceEquals oder Equals Methode.

Die GetHashCode Methode kann durch einen abgeleiteten Typ überschrieben werden. Wenn GetHashCode ist nicht außer Kraft gesetzt, Hashcodes für Verweistypen berechnet werden, durch Aufrufen der Object.GetHashCode Methode der Basisklasse, die einen Hashcode berechnet basierend auf ein Objekt Verweis; Weitere Informationen, finden Sie unter RuntimeHelpers.GetHashCode. Das heißt, zwei Objekte auf dem die ReferenceEquals -Methode zurückkehrt true haben identische Hashcodes. Wenn Werttypen nicht außer Kraft setzen GetHashCodedie ValueType.GetHashCode -Methode der Basisklasse verwendet Reflektion, um den Hashcode anhand der Werte der Felder des Typs zu berechnen. Werttypen, deren Felder identische Werte haben, haben also gleich Hashcodes. Weitere Informationen zum Überschreiben GetHashCode, finden Sie im Abschnitt "Hinweise zur Vererbung".

System_CAPS_warningWarnung

Wenn Sie überschreiben die GetHashCode , Sie sollten auch-methodenüberschreibung Equals, und umgekehrt. Wenn die überschriebene Equals -Methode zurückkehrt true Wenn werden zwei Objekte auf Gleichheit, die außer Kraft gesetzte getestet GetHashCode Methode muss für die beiden Objekte den gleichen Wert zurück.

Wenn ein Objekt, das in einer Hashtabelle als Schlüssel verwendet wird, keine geeignete Implementierung von bietet GetHashCode, Sie können einen Hashcode-Standardanbieter angeben, durch Angabe einer IEqualityComparer -Implementierung, die eine der Überladungen der der Hashtable Klassenkonstruktor.

Beim Aufrufen der GetHashCode Methode einer Klasse in der Windows-Runtime, es stellt das Standardverhalten für Klassen, die nicht außer Kraft setzen GetHashCode. Dies ist Teil der Unterstützung von .NET Framework für die Windows-Runtime (siehe .NET Framework-Unterstützung für Windows Store-Apps und Windows-Runtime). Klassen in der Windows-Runtime erben nicht Object, und zurzeit nicht implementieren eine GetHashCode. Allerdings sie angezeigt werden, damit ToString, Equals(Object), und GetHashCode Methoden, wenn Sie in c# oder Visual Basic-Code werden verwendet, und die .NET Framework das Standardverhalten für diese Methoden bietet.

System_CAPS_noteHinweis

Windows-RuntimeKlassen, die in c# oder Visual Basic geschrieben sind, können außer Kraft setzen die GetHashCode Methode.

Hinweise für Vererber:

Eine Hashfunktion wird zum schnellen Generieren einer Zahl (Hashcode) verwendet, die dem Wert eines Objekts entspricht. Hashfunktionen für jeden Typ in der Regel spezifisch sind und für die Eindeutigkeit, müssen mindestens eines der Instanzfelder als Eingabe verwenden. Hashcodes sollten nicht mit den Werten von statischen Feldern berechnet werden.

Für Klassen abgeleitete Object, GetHashCode -Methode der Basisklasse delegieren kann Object.GetHashCode() Implementierung nur, wenn die abgeleitete Klasse Gleichheit als Verweisgleichheit definiert. Die standardmäßige Implementierung des GetHashCode Referenzzwecken Typen zurückgibt einen Hashcode, der zurückgegeben wird, indem Sie entspricht der RuntimeHelpers.GetHashCode(Object) Methode. Sie können außer Kraft setzen GetHashCode für unveränderliche Verweistypen. Im Allgemeinen für änderbare Referenztypen, Sie sollten eine Überschreibung GetHashCode nur, wenn:

  • Sie den Hashcode aus Feldern ableiten können, die nicht geändert werden; oder

  • Sie können sicherstellen, dass der Hashcode des ein änderbares Objekt nicht ändert, während das Objekt in einer Auflistung enthalten ist, die abhängig von dessen Hashcode.

Andernfalls könnte das änderbare Objekt möglicherweise in der Hashtabelle verloren gehen. Wenn Sie sich entschließen, überschreiben GetHashCode für einen änderbaren Referenztyp Ihrer Dokumentation sollte unbedingt verdeutlicht werden, dass Benutzer Ihres Typs Objektwerte nicht ändern sollten, während das Objekt in einer Hashtabelle gespeichert ist.

Bei Werttypen ValueType.GetHashCode Hash Code stellt eine Standardimplementierung bereit, die Reflektion verwendet. Erwägen Sie, ob Sie es für eine bessere Leistung zu überschreiben.

System_CAPS_noteHinweis

Weitere Informationen und Beispiele, die Hashcodes auf verschiedenste Art und Weise berechnen, finden Sie im Beispielabschnitt.

Eine Hashfunktion muss die folgenden Eigenschaften aufweisen:

  • Wenn zwei Objekte als gleich, vergleichen die GetHashCode Methode für jedes Objekt muss den gleichen Wert zurück. Jedoch, wenn die beiden Objekte nicht gleich, Vergleich der GetHashCode Methoden für die beiden Objekte müssen keine unterschiedliche Werte zurückgeben.

  • Die GetHashCode Methode für ein Objekt muss immer zurückgeben, denselben Hashcode, solange es ist keine Änderung an der Zustand des Objekts, das den Rückgabewert, der des Objekts bestimmt Equals Methode. Beachten Sie, dass dies nur während der aktuellen Ausführung einer Anwendung "true" ist und ein anderen Hashcode zurückgegeben werden kann, wenn die Anwendung erneut ausgeführt wird.

  • Für optimale Leistung soll eine Hashfunktion eine gleichmäßige Verteilung für alle Eingaben generieren, einschließlich stark gruppierter Eingabe. Eine Folge ist, dass kleinere Änderungen an den Objektzustand in umfangreichen Änderungen an den resultierenden Hashcode für eine optimale Leistung der Hash-Tabelle führen soll.

  • Hashfunktionen sollten kostengünstigen berechnet werden.

  • Die GetHashCode Methode sollte keine Ausnahmen auslösen.

Z. B. die Implementierung von der GetHashCode Methode bereitgestellt wird, indem Sie die String Klasse gibt identische Hashcodes für identische Zeichenfolgenwerte zurück. Aus diesem Grund zwei String Objekte den gleichen Hashcode zurückgeben, wenn diese denselben Zeichenfolgenwert darstellen. Die Methode verwendet außerdem alle Zeichen in der Zeichenfolge verhältnismäßig zufällig verteilte Ausgabe zu generieren, auch wenn die Eingabe in bestimmten Bereichen gruppiert ist (z. B. viele Benutzer möglicherweise Zeichenfolgen, die nur die unteren 128 ASCII-Zeichen enthalten, obwohl eine Zeichenfolge, die die 65.535 Unicode-Zeichen enthalten kann).

Bietet eine gute Hashfunktion für eine Klasse kann die Leistung dieser Objekte hinzugefügt. eine Hashtabelle spürbar verringern. In einer Hashtabelle mit Schlüsseln, die eine gute Implementierung einer Hashfunktion bereitstellen, wird die Suche nach einem Element Konstanten Zeit (z. B. eine o(1)-Operation). In einer Hashtabelle durch eine schlechte Implementierung einer Hashfunktion, die Leistung einer Suche hängt die Anzahl der Elemente in der Hashtabelle (z. B. eine O (n) Vorgang, wobei n ist die Anzahl der Elemente in der Hashtabelle). Ein böswilliger Benutzer kann Daten einzugeben, die die Anzahl der Konflikte, vergrößert die deutlich die Leistung der Anwendung beeinträchtigen können, die abhängig von Hashtabellen in den folgenden Situationen:

  • Wenn Hashfunktionen häufig Konflikte erzeugen.

  • Wenn eine große Menge von Objekten in einer Hashtabelle Hashcodes, die gleich sind oder ungefähr gleich untereinander erzeugen.

  • Wenn Benutzer die Eingabe der Daten aus denen berechnete Hashcode.

Abgeleitete Klassen, die außer Kraft setzen GetHashCode müssen auch überschreiben Equals um sicherzustellen, dass zwei Objekte als gleich betrachtet, denselben Hashcode haben, andernfalls die Hashtable Typ funktionieren eventuell nicht richtig.

Einer der einfachsten Möglichkeiten, einen Hashcode für einen numerischen Wert zu berechnen, der der gleichen oder einer kleineren Bereich als hat die Int32 ist einfach, der Wert zurückgegeben. Das folgende Beispiel zeigt eine Implementierung für eine Number Struktur.

Public Structure Number
   Private n As Integer

   Public Sub New(value As Integer)
      n = value
   End Sub

   Public ReadOnly Property Value As Integer
      Get
         Return n
      End Get
   End Property

   Public Overrides Function Equals(obj As Object) As Boolean
      If obj Is Nothing OrElse Not TypeOf obj Is Number Then
         Return False
      Else
         Return n = CType(obj, Number).n
      End If
   End Function      

   Public Overrides Function GetHashCode() As Integer
      Return n
   End Function

   Public Overrides Function ToString() As String
      Return n.ToString()
   End Function
End Structure

Module Example
   Public Sub Main()
      Dim rnd As New Random()
      For ctr As Integer = 0 To 9
         Dim randomN As Integer = rnd.Next(Int32.MinValue, Int32.MaxValue)
         Dim n As New Number(randomN)
         Console.WriteLine("n = {0,12}, hash code = {1,12}", n, n.GetHashCode())
      Next
   End Sub
End Module
' The example displays output like the following:
'       n =   -634398368, hash code =   -634398368
'       n =   2136747730, hash code =   2136747730
'       n =  -1973417279, hash code =  -1973417279
'       n =   1101478715, hash code =   1101478715
'       n =   2078057429, hash code =   2078057429
'       n =   -334489950, hash code =   -334489950
'       n =    -68958230, hash code =    -68958230
'       n =   -379951485, hash code =   -379951485
'       n =    -31553685, hash code =    -31553685
'       n =   2105429592, hash code =   2105429592

In vielen Fällen hat einen Typ mehrere Datenfelder, die beim Generieren des Hashcodes einbezogen werden können. Eine Möglichkeit, einen Hashcode zu generieren, kombinieren diese Felder mithilfe von ist ein XOR (eXclusive OR) Vorgang, wie im folgenden Beispiel gezeigt.

' A type that represents a 2-D point.
Public Structure Point
    Private x As Integer
    Private y As Integer

    Public Sub New(x As Integer, y As Integer)
       Me.x = x
       Me.y = y
    End Sub

    Public Overrides Function Equals(obj As Object) As Boolean
       If Not TypeOf obj Is Point Then Return False

       Dim p As Point = CType(obj, Point)
       Return x = p.x And y = p.y
    End Function

    Public Overrides Function GetHashCode() As Integer 
        Return x Xor y
    End Function 
End Structure 

Public Module Example
   Public Sub Main() 
      Dim pt As New Point(5, 8)
      Console.WriteLine(pt.GetHashCode())

      pt = New Point(8, 5)
      Console.WriteLine(pt.GetHashCode())
   End Sub 
End Module   

Das vorherige Beispiel gibt möglicherweise denselben Hashcode für n1, (n2) und (n2, n1) zurück und generiert damit mehr Konflikte, als erwünscht sind. Eine Reihe von Lösungen sind verfügbar, sodass Hashcodes in diesen Fällen nicht identisch sind. Eine besteht darin, den Hashcode des Zurückgeben einer Tuple -Objekt, das die Reihenfolge der jedes Feld entspricht. Das folgende Beispiel zeigt eine mögliche Implementierung, verwendet die Tuple(Of T1, T2) Klasse. Beachten Sie jedoch, die die Beeinträchtigung der Systemleistung der Instanziierung einer Tuple Objekt kann erhebliche Auswirkungen auf die allgemeine Leistung einer Anwendung, in der großen Anzahl von Objekten in Hashtabellen gespeichert.

Public Structure Point
    Private x As Integer
    Private y As Integer

    Public Sub New(x As Integer, y As Integer)
       Me.x = x
       Me.y = y
    End Sub

    Public Overrides Function Equals(obj As Object) As Boolean
       If Not TypeOf obj Is Point Then Return False

       Dim p As Point = CType(obj, Point)
       Return x = p.x And y = p.y
    End Function

    Public Overrides Function GetHashCode() As Integer 
        Return Tuple.Create(x, y).GetHashCode()
    End Function 
End Structure 

Public Module Example
    Public Sub Main() 
        Dim pt As New Point(5, 8)
        Console.WriteLine(pt.GetHashCode())

        pt = New Point(8, 5)
        Console.WriteLine(pt.GetHashCode())
    End Sub 
End Module         
' The example displays the following output:
'       173
'       269

Eine zweite alternative Lösung umfasst die Gewichtung der einzelnen Hashcodes von links-Verschiebung der Hashcodes von aufeinander folgenden Feldern von zwei oder mehr Bits. Optimal, anstatt verworfen werden, Bits verschoben hinter Bit 31 umschließen soll statt verworfen werden. Da von der Left Shift-Operatoren in c# und Visual Basic Bits verworfen werden, erfordert dies eine linke UMSCHALT-Wrap-Methode wie folgt erstellen:

Public Function ShiftAndWrap(value As Integer, positions As Integer) As Integer
   positions = positions And &h1F

   ' Save the existing bit pattern, but interpret it as an unsigned integer.
   Dim number As UInteger = BitConverter.ToUInt32(BitConverter.GetBytes(value), 0)
   ' Preserve the bits to be discarded.
   Dim wrapped AS UInteger = number >> (32 - positions)
   ' Shift and wrap the discarded bits.
   Return BitConverter.ToInt32(BitConverter.GetBytes((number << positions) Or wrapped), 0)
End Function

Im folgende Beispiel verwendet dann diese UMSCHALT-Wrap-Methode den Hashcode berechnet die Point Struktur, die in den vorherigen Beispielen verwendet.

Public Structure Point
    Private x As Integer
    Private y As Integer

    Public Sub New(x As Integer, y As Integer)
       Me.x = x
       Me.y = y
    End Sub

    Public Overrides Function Equals(obj As Object) As Boolean
       If Not TypeOf obj Is Point Then Return False

       Dim p As Point = CType(obj, Point)
       Return x = p.x And y = p.y
    End Function

    Public Overrides Function GetHashCode() As Integer 
        Return ShiftAndWrap(x.GetHashCode(), 2) XOr y.GetHashCode()
    End Function 

    Private Function ShiftAndWrap(value As Integer, positions As Integer) As Integer
        positions = positions And &h1F

        ' Save the existing bit pattern, but interpret it as an unsigned integer.
        Dim number As UInteger = BitConverter.ToUInt32(BitConverter.GetBytes(value), 0)
        ' Preserve the bits to be discarded.
        Dim wrapped AS UInteger = number >> (32 - positions)
        ' Shift and wrap the discarded bits.
        Return BitConverter.ToInt32(BitConverter.GetBytes((number << positions) Or wrapped), 0)
    End Function
End Structure 

Module Example
   Public Sub Main()
        Dim pt As New Point(5, 8)
        Console.WriteLine(pt.GetHashCode())

        pt = New Point(8, 5)
        Console.WriteLine(pt.GetHashCode())
   End Sub
End Module
' The example displays the following output:
'       28
'       37

Universelle Windows-Plattform
Verfügbar seit 8
.NET Framework
Verfügbar seit 1.1
Portierbare Klassenbibliothek
Unterstützt in: portierbare .NET-Plattformen
Silverlight
Verfügbar seit 2.0
Windows Phone Silverlight
Verfügbar seit 7.0
Windows Phone
Verfügbar seit 8.1
Zurück zum Anfang
Anzeigen: