Object.GetHashCode Methode

Definition

Fungiert als Standardhashfunktion.

public:
 virtual int GetHashCode();
public virtual int GetHashCode ();
abstract member GetHashCode : unit -> int
override this.GetHashCode : unit -> int
Public Overridable Function GetHashCode () As Integer

Gibt zurück

Int32

Ein Hashcode für das aktuelle Objekt.

Beispiele

Eine der einfachsten Möglichkeiten zum Berechnen eines Hashcodes für einen numerischen Wert mit demselben oder einem kleineren Bereich als der Int32 Typ besteht darin, diesen Wert einfach zurückzugeben. Das folgende Beispiel zeigt eine solche Implementierung für eine Number Struktur.

using System;

public struct Number
{
   private int n;

   public Number(int value)
   {
      n = value;
   }

   public int Value
   {
      get { return n; }
   }

   public override bool Equals(Object obj)
   {
      if (obj == null || ! (obj is Number))
         return false;
      else
         return n == ((Number) obj).n;
   }

   public override int GetHashCode()
   {
      return n;
   }

   public override string ToString()
   {
      return n.ToString();
   }
}

public class Example
{
   public static void Main()
   {
      Random rnd = new Random();
      for (int ctr = 0; ctr <= 9; ctr++) {
         int randomN = rnd.Next(Int32.MinValue, Int32.MaxValue);
         Number n = new Number(randomN);
         Console.WriteLine("n = {0,12}, hash code = {1,12}", n, n.GetHashCode());
      }
   }
}
// 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
open System

[<Struct; CustomEquality; NoComparison>]
type Number(value: int) =
    member _.Value = value

    override _.Equals(obj) =
        match obj with
        | :? Number as n ->
            n.Value = value
        | _ -> false

    override _.GetHashCode() =
        value

    override _.ToString() =
        string value

let rnd = Random()
for _ = 0 to 9 do
    let randomN = rnd.Next(Int32.MinValue, Int32.MaxValue)
    let n = Number randomN
    printfn $"n = {n,12}, hash code = {n.GetHashCode(),12}"
// 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
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

Häufig verfügt ein Typ über mehrere Datenfelder, die daran teilnehmen können, den Hashcode zu generieren. Eine Möglichkeit zum Generieren eines Hashcodes besteht darin, diese Felder mithilfe eines XOR (eXclusive OR) Vorgangs zu kombinieren, wie im folgenden Beispiel gezeigt.

using System;

// A type that represents a 2-D point.
public struct Point
{
    private int x;
    private int y;

    public Point(int x, int y)
    {
       this.x = x;
       this.y = y;
    }

    public override bool Equals(Object obj)
    {
       if (! (obj is Point)) return false;

       Point p = (Point) obj;
       return x == p.x & y == p.y;
    }

    public override int GetHashCode()
    {
        return x ^ y;
    }
}

public class Example
{
   public static void Main()
   {
      Point pt = new Point(5, 8);
      Console.WriteLine(pt.GetHashCode());

      pt = new Point(8, 5);
      Console.WriteLine(pt.GetHashCode());
   }
}
// The example displays the following output:
//       13
//       13
// A type that represents a 2-D point.
[<Struct; CustomEquality; NoComparison>]
type Point(x: int, y: int) =
    member _.X = x
    member _.Y = y

    override _.Equals(obj) =
        match obj with
        | :? Point as p ->
            x = p.X && y = p.Y
        | _ -> 
            false

    override _.GetHashCode() =
        x ^^^ y

let pt = Point(5, 8)
printfn $"{pt.GetHashCode()}"

let pt2 = Point(8, 5)
printfn $"{pt.GetHashCode()}"
// The example displays the following output:
//       13
//       13
' 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

Im vorherigen Beispiel wird derselbe Hashcode für (n1, n2) und (n2, n1) zurückgegeben, sodass möglicherweise mehr Kollisionen generiert werden als wünschenswert. Eine Reihe von Lösungen ist verfügbar, damit Hashcodes in diesen Fällen nicht identisch sind. Eine besteht darin, den Hashcode eines Tuple Objekts zurückzugeben, der die Reihenfolge jedes Felds widerspiegelt. Das folgende Beispiel zeigt eine mögliche Implementierung, die die Tuple<T1,T2> Klasse verwendet. Beachten Sie jedoch, dass sich der Leistungsaufwand beim Instanziieren eines Tuple Objekts erheblich auf die Gesamtleistung einer Anwendung auswirken kann, die große Anzahl von Objekten in Hashtabellen speichert.

using System;

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

    public Point(int x, int y)
    {
       this.x = x;
       this.y = y;
    }

    public override bool Equals(Object obj)
    {
        if (obj is Point)
        {
            Point p = (Point) obj;
            return x == p.x & y == p.y;
        }
        else
        {
            return false;
        }      
    }

    public override int GetHashCode()
    {
        return Tuple.Create(x, y).GetHashCode();
    }
}

public class Example
{
   public static void Main()
   {
        Point pt = new Point(5, 8);
        Console.WriteLine(pt.GetHashCode());

        pt = new Point(8, 5);
        Console.WriteLine(pt.GetHashCode());
   }
}
// The example displays the following output:
//       173
//       269
[<Struct; CustomEquality; NoComparison>]
type Point(x: int, y: int) =
    member _.X = x
    member _.Y = y

    override _.Equals(obj) =
        match obj with
        | :? Point as p ->
            x = p.X && y = p.Y
        | _ -> 
            false

    override _.GetHashCode() =
        (x, y).GetHashCode()

let pt = Point(5, 8)
printfn $"{pt.GetHashCode()}"

let pt2 = Point(8, 5)
printfn $"{pt2.GetHashCode()}"
// The example displays the following output:
//       173
//       269
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 das Gewichten der einzelnen Hashcodes, indem sie die Hashcodes aufeinander folgender Felder nach zwei oder mehr Bit verschieben. Optimalerweise sollten Bits, die über Bit 31 hinaus verschoben wurden, umgebrochen werden, anstatt verworfen zu werden. Da Bits von den Operatoren der linken Schicht sowohl in C# als auch in Visual Basic verworfen werden, erfordert dies die Erstellung einer linken Umschalt- und Umbruchmethode wie folgt:

public int ShiftAndWrap(int value, int positions)
{
    positions = positions & 0x1F;

    // Save the existing bit pattern, but interpret it as an unsigned integer.
    uint number = BitConverter.ToUInt32(BitConverter.GetBytes(value), 0);
    // Preserve the bits to be discarded.
    uint wrapped = number >> (32 - positions);
    // Shift and wrap the discarded bits.
    return BitConverter.ToInt32(BitConverter.GetBytes((number << positions) | wrapped), 0);
}
let shiftAndWrap (value: int) positions =
    let positions = positions &&& 0x1F

    // Save the existing bit pattern, but interpret it as an unsigned integer.
    let number = BitConverter.ToUInt32(BitConverter.GetBytes value, 0)
    // Preserve the bits to be discarded.
    let wrapped = number >>> (32 - positions)
    // Shift and wrap the discarded bits.
    BitConverter.ToInt32(BitConverter.GetBytes((number <<< positions) ||| wrapped), 0)
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 folgenden Beispiel wird dann diese Umschalt- und Umbruchmethode verwendet, um den Hashcode der Struktur zu berechnen, die Point in den vorherigen Beispielen verwendet wird.

using System;

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

    public Point(int x, int y)
    {
       this.x = x;
       this.y = y;
    }

    public override bool Equals(Object obj)
    {
       if (!(obj is Point)) return false;

       Point p = (Point) obj;
       return x == p.x & y == p.y;
    }

    public override int GetHashCode()
    {
        return ShiftAndWrap(x.GetHashCode(), 2) ^ y.GetHashCode();
    }

    private int ShiftAndWrap(int value, int positions)
    {
        positions = positions & 0x1F;

        // Save the existing bit pattern, but interpret it as an unsigned integer.
        uint number = BitConverter.ToUInt32(BitConverter.GetBytes(value), 0);
        // Preserve the bits to be discarded.
        uint wrapped = number >> (32 - positions);
        // Shift and wrap the discarded bits.
        return BitConverter.ToInt32(BitConverter.GetBytes((number << positions) | wrapped), 0);
    }
}

public class Example
{
   public static void Main()
   {
        Point pt = new Point(5, 8);
        Console.WriteLine(pt.GetHashCode());

        pt = new Point(8, 5);
        Console.WriteLine(pt.GetHashCode());
   }
}
// The example displays the following output:
//       28
//       37
open System

[<Struct; CustomEquality; NoComparison>]
type Point(x: int, y: int) =
    member _.X = x
    member _.Y = y
    override _.Equals(obj) =
        match obj with
        | :? Point as p ->
            x = p.X && y = p.Y
        | _ -> 
            false

    override this.GetHashCode() =
        this.ShiftAndWrap(x.GetHashCode(), 2) ^^^ y.GetHashCode()

    member _.ShiftAndWrap(value, positions) =
        let positions = positions &&& 0x1F

        // Save the existing bit pattern, but interpret it as an unsigned integer.
        let number = BitConverter.ToUInt32(BitConverter.GetBytes value, 0)
        // Preserve the bits to be discarded.
        let wrapped = number >>> (32 - positions)
        // Shift and wrap the discarded bits.
        BitConverter.ToInt32(BitConverter.GetBytes((number <<< positions) ||| wrapped), 0)

let pt = Point(5, 8)
printfn $"{pt.GetHashCode()}"

let pt2 = Point(8, 5)
printfn $"{pt2.GetHashCode()}"
// The example displays the following output:
//       28
//       37
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

Hinweise

Ein Hashcode ist ein numerischer Wert, der zum Einfügen und Identifizieren eines Objekts in einer hashbasierten Auflistung wie der Klasse, der Dictionary<TKey,TValue> Hashtable Klasse oder eines Typs verwendet wird, der von der DictionaryBase Klasse abgeleitet ist. Die GetHashCode Methode stellt diesen Hashcode für Algorithmen bereit, die schnelle Überprüfungen der Objektgleichheit benötigen.

Hinweis

Informationen dazu, wie Hashcodes in Hashtabellen und für einige zusätzliche Hashcodealgorithmen verwendet werden, finden Sie im Eintrag zur Hashfunktion in Wikipedia.

Zwei Objekte, die gleich Rückgabehashcodes sind, die gleich sind. Die Umgekehrte ist jedoch nicht wahr: Gleichheitshashcodes impliziert keine Objektgleichheit, da verschiedene (ungleiche) Objekte identische Hashcodes aufweisen können. Darüber hinaus garantiert .NET nicht die Standardimplementierung der GetHashCode Methode, und der Wert, den diese Methode zurückgibt, kann sich zwischen .NET-Implementierungen unterscheiden, z. B. verschiedene Versionen von .NET Framework und .NET Core und Plattformen, z. B. 32-Bit- und 64-Bit-Plattformen. Aus diesen Gründen verwenden Sie die Standardimplementierung dieser Methode nicht als eindeutigen Objektbezeichner für Hashingzwecke. Es folgen zwei Folgen:

  • Sie sollten nicht davon ausgehen, dass gleiche Hashcodes die Objektgleichheit bedeuten.

  • Sie sollten niemals einen Hashcode außerhalb der Anwendungsdomäne beibehalten oder verwenden, in der sie erstellt wurde, da dasselbe Objekt über Anwendungsdomänen, Prozesse und Plattformen hinweg hashen kann.

Warnung

Ein Hashcode ist für eine effiziente Einfüge- und Nachschlagefunktion in Sammlungen vorgesehen, die auf einer Hashtabelle basieren. Ein Hashcode ist kein dauerhafter Wert. Aus diesem Grund:

  • Serialisieren Sie keine Hashcodewerte, oder speichern Sie sie in Datenbanken.
  • Verwenden Sie den Hashcode nicht als Schlüssel, um ein Objekt aus einer schlüsselierten Auflistung abzurufen.
  • Senden Sie hashcodes nicht über Anwendungsdomänen oder Prozesse hinweg. In einigen Fällen können Hashcodes pro Prozess oder pro Anwendungsdomäne berechnet werden.
  • Verwenden Sie den Hashcode nicht anstelle eines Werts, der von einer kryptografischen Hashfunktion zurückgegeben wird, wenn Sie einen kryptografisch starken Hash benötigen. Verwenden Sie für kryptografische Hashes eine Klasse, die von der oder System.Security.Cryptography.KeyedHashAlgorithm der System.Security.Cryptography.HashAlgorithm Klasse abgeleitet ist.
  • Testen Sie nicht die Gleichheit von Hashcodes, um zu bestimmen, ob zwei Objekte gleich sind. (Ungleiche Objekte können identische Hashcodes aufweisen.) Rufen Sie die ReferenceEquals Methode Equals auf, um die Gleichheit zu testen.

Die GetHashCode Methode kann von einem abgeleiteten Typ außer Kraft gesetzt werden. Wenn GetHashCode nicht außer Kraft gesetzt wird, werden Hashcodes für Referenztypen berechnet, indem die Object.GetHashCode Methode der Basisklasse aufgerufen wird, die einen Hashcode basierend auf dem Verweis eines Objekts berechnet. Weitere Informationen finden Sie unter RuntimeHelpers.GetHashCode. Mit anderen Worten, zwei Objekte, für die die ReferenceEquals Methode zurückgegeben wird, weisen identische Hashcodes auf true . Wenn Werttypen nicht außer Kraft setzen GetHashCode, verwendet die ValueType.GetHashCode Methode der Basisklasse Spiegelung, um den Hashcode basierend auf den Werten der Felder des Typs zu berechnen. Mit anderen Worten, Werttypen, deren Felder gleich Werte haben, haben gleiche Hashcodes. Weitere Informationen zum Überschreiben GetHashCodefinden Sie im Abschnitt "Notizen zu Erben".

Warnung

Wenn Sie die GetHashCode Methode außer Kraft setzen, sollten Sie die Methode auch außer Kraft setzen und umgekehrt.Equals Wenn ihre überschriebene Equals Methode zurückgibt true , wenn zwei Objekte auf Gleichheit getestet werden, muss ihre überschriebene GetHashCode Methode denselben Wert für die beiden Objekte zurückgeben.

Wenn ein Objekt, das als Schlüssel in einer Hashtabelle verwendet wird, keine nützliche Implementierung GetHashCodebereitstellt, können Sie einen Hashcodeanbieter angeben, indem Sie eine IEqualityComparer Implementierung an eine der Überladungen des Hashtable Klassenkonstruktors bereitstellen.

Hinweise für die Windows-Runtime

Wenn Sie die GetHashCode Methode für eine Klasse im Windows-Runtime aufrufen, stellt sie das Standardverhalten für Klassen bereit, die nicht außer Kraft setzenGetHashCode. Dies ist Teil der Unterstützung, die der .NET Framework für die Windows-Runtime bereitstellt (siehe .NET Framework Support für Windows Store Apps und Windows-Runtime). Klassen in der Windows-Runtime erben Objectnicht und implementieren GetHashCodederzeit keine . Sie scheinen ToStringEquals(Object)jedoch , und GetHashCode Methoden, wenn Sie sie in Ihrem C# oder Visual Basic Code verwenden, und die .NET Framework stellt das Standardverhalten für diese Methoden bereit.

Hinweis

Windows-Runtime Klassen, die in C# geschrieben wurden, oder Visual Basic können die GetHashCode Methode außer Kraft setzen.

Hinweise für Vererber

Eine Hashfunktion wird verwendet, um schnell eine Zahl (Hashcode) zu generieren, die dem Wert eines Objekts entspricht. Hashfunktionen sind in der Regel für jeden Typ spezifisch und müssen mindestens eines der Instanzfelder als Eingabe verwenden. Hashcodes sollten nicht mithilfe der Werte statischer Felder berechnet werden.

Bei Klassen, die von der ObjectMethode abgeleitet werden, kann die GetHashCode Methode nur an die Basisklassenimplementierung GetHashCode() delegieren, wenn die abgeleitete Klasse die Gleichheit definiert, um auf die Gleichbehandlung zu verweisen. Die Standardimplementierung für GetHashCode() Referenztypen gibt einen Hashcode zurück, der der von der GetHashCode(Object) Methode zurückgegebenen entspricht. Sie können für unveränderliche Referenztypen außer Kraft setzen GetHashCode() . Im Allgemeinen sollten Sie bei stummgeschalteten Referenztypen nur außer GetHashCode() Kraft setzen, wenn:

  • Sie können den Hashcode aus Feldern berechnen, die nicht stummgeschaltet sind; Oder
  • Sie können sicherstellen, dass sich der Hashcode eines stummgeschalteten Objekts nicht ändert, während das Objekt in einer Auflistung enthalten ist, die auf seinem Hashcode basiert.

Andernfalls denken Sie möglicherweise, dass das stummgeschaltete Objekt in der Hashtabelle verloren geht. Wenn Sie für einen stummgeschalteten Referenztyp außer Kraft GetHashCode() setzen möchten, sollte Ihre Dokumentation klar machen, dass Benutzer Ihres Typs die Objektwerte nicht ändern sollten, während das Objekt in einer Hashtabelle gespeichert ist.

Für Werttypen stellt eine Standard-Hashcodeimplementierung bereit, GetHashCode() die Spiegelung verwendet. Sie sollten es für eine bessere Leistung außer Kraft setzen.

Weitere Informationen und Beispiele, die Hashcodes auf verschiedene Weise berechnen, finden Sie im Abschnitt "Beispiele".

Eine Hashfunktion muss die folgenden Eigenschaften aufweisen:

  • Wenn zwei Objekte gleich vergleichen, muss die GetHashCode() Methode für jedes Objekt denselben Wert zurückgeben. Wenn jedoch zwei Objekte nicht gleich vergleichen, müssen die Methoden für die GetHashCode() beiden Objekte keine unterschiedlichen Werte zurückgeben.

  • Die GetHashCode() Methode für ein Objekt muss den gleichen Hashcode konsistent zurückgeben, solange keine Änderung an dem Objektzustand vorhanden ist, der den Rückgabewert der System.Object.Equals-Methode des Objekts bestimmt. Beachten Sie, dass dies nur für die aktuelle Ausführung einer Anwendung gilt und dass ein anderer Hashcode zurückgegeben werden kann, wenn die Anwendung erneut ausgeführt wird.

  • Für die beste Leistung sollte eine Hashfunktion eine gleichmäßige Verteilung für alle Eingaben generieren, einschließlich eingaben, die stark gruppiert sind. Eine Implication besteht darin, dass kleine Änderungen an dem Objektzustand zu großen Änderungen an dem resultierenden Hashcode führen sollten, um die beste Hashtabellenleistung zu erzielen.

  • Hashfunktionen sollten kostengünstig sein, um zu berechnen.

  • Die GetHashCode() Methode sollte keine Ausnahmen auslösen.

Beispielsweise gibt die Implementierung der von der GetHashCode() String Klasse bereitgestellten Methode identische Hashcodes für identische Zeichenfolgenwerte zurück. Daher geben zwei String Objekte den gleichen Hashcode zurück, wenn sie den gleichen Zeichenfolgenwert darstellen. Außerdem verwendet die Methode alle Zeichen in der Zeichenfolge, um eine relativ zufällig verteilte Ausgabe zu generieren, auch wenn die Eingabe in bestimmten Bereichen gruppiert ist (z. B. viele Benutzer haben Zeichenfolgen, die nur die unteren 128 ASCII-Zeichen enthalten, auch wenn eine Zeichenfolge eine der 65.535 Unicode-Zeichen enthalten kann).

Die Bereitstellung einer guten Hashfunktion in einer Klasse kann die Leistung des Hinzufügens dieser Objekte zu einer Hashtabelle erheblich beeinflussen. In einer Hashtabelle mit Schlüsseln, die eine gute Implementierung einer Hashfunktion bereitstellen, dauert die Suche nach einem Element konstanten Zeit (z. B. ein O(1)-Vorgang). In einer Hashtabelle mit einer schlechten Implementierung einer Hashfunktion hängt die Leistung einer Suche von der Anzahl der Elemente in der Hashtabelle ab (z. B. ein O(n)-Vorgang, wobei n die Anzahl der Elemente in der Hashtabelle liegt. Ein böswilliger Benutzer kann Daten eingeben, die die Anzahl der Kollisionen erhöhen, wodurch die Leistung von Anwendungen, die von Hashtabellen abhängig sind, unter den folgenden Bedingungen erheblich verringert werden kann:

  • Wenn Hashfunktionen häufige Kollisionen erzeugen.

  • Wenn ein großer Anteil von Objekten in einer Hashtabelle Hashcodes erzeugt, die gleich oder ungefähr gleich einem anderen sind.

  • Wenn Benutzer die Daten eingeben, aus denen der Hashcode berechnet wird.

Abgeleitete Klassen, die außer GetHashCode() Kraft setzen müssen, müssen auch außer Equals(Object) Kraft setzen, um sicherzustellen, dass zwei Objekte, die gleich sind, den gleichen Hashcode haben. Andernfalls funktioniert der Hashtable Typ möglicherweise nicht ordnungsgemäß.

Gilt für:

Siehe auch