Object.GetHashCode Méthode
Définition
Sert de fonction de hachage par défaut.Serves as the default hash function.
public:
virtual int GetHashCode();
public virtual int GetHashCode ();
abstract member GetHashCode : unit -> int
override this.GetHashCode : unit -> int
Public Overridable Function GetHashCode () As Integer
Retours
Code de hachage pour l'objet actuel.A hash code for the current object.
Exemples
L’une des façons les plus simples de calculer un code de hachage pour une valeur numérique qui a la même plage ou une plus petite plage que le type de Int32 est simplement de retourner cette valeur.One of the simplest ways to compute a hash code for a numeric value that has the same or a smaller range than the Int32 type is to simply return that value. L’exemple suivant montre une implémentation de ce type pour une structure Number
.The following example shows such an implementation for a Number
structure.
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
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
Souvent, un type a plusieurs champs de données qui peuvent participer à la génération du code de hachage.Frequently, a type has multiple data fields that can participate in generating the hash code. Une façon de générer un code de hachage consiste à combiner ces champs à l’aide d’une opération de XOR (eXclusive OR)
, comme indiqué dans l’exemple suivant.One way to generate a hash code is to combine these fields using an XOR (eXclusive OR)
operation, as shown in the following example.
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.
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
L’exemple précédent retourne le même code de hachage pour (N1, N2) et (N2, N1). par conséquent, il peut générer plus de collisions que ce qui est souhaitable.The previous example returns the same hash code for (n1, n2) and (n2, n1), and so may generate more collisions than are desirable. Un certain nombre de solutions sont disponibles afin que les codes de hachage dans ces cas ne soient pas identiques.A number of solutions are available so that hash codes in these cases are not identical. La première consiste à retourner le code de hachage d’un objet Tuple
qui reflète l’ordre de chaque champ.One is to return the hash code of a Tuple
object that reflects the order of each field. L’exemple suivant montre une implémentation possible qui utilise la classe Tuple<T1,T2>.The following example shows a possible implementation that uses the Tuple<T1,T2> class. Notez, cependant, que la surcharge de performance liée à l’instanciation d’un objet Tuple
peut avoir un impact significatif sur les performances globales d’une application qui stocke un grand nombre d’objets dans des tables de hachage.Note, though, that the performance overhead of instantiating a Tuple
object may significantly impact the overall performance of an application that stores large numbers of objects in hash tables.
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 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
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
Une deuxième solution consiste à pondérer les codes de hachage individuels en décalant les codes de hachage des champs successifs de deux bits ou plus.A second alternative solution involves weighting the individual hash codes by left-shifting the hash codes of successive fields by two or more bits. De manière optimale, au lieu d’être ignorées, les bits décalés au-delà du bit 31 doivent être encapsulés au lieu d’être ignorés.Optimally, instead of being discarded, bits shifted beyond bit 31 should wrap around rather than be discarded. Étant donné que les bits sont ignorés par les opérateurs de décalage vers C# la gauche dans et Visual Basic, il est nécessaire de créer une méthode de décalage vers la gauche et de retour à la ligne comme suit :Since bits are discarded by the left-shift operators in both C# and Visual Basic, this requires creating a left shift-and-wrap method like the following:
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);
}
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
L’exemple suivant utilise ensuite cette méthode Shift-and-Wrap pour calculer le code de hachage de la structure Point
utilisée dans les exemples précédents.The following example then uses this shift-and-wrap method to compute the hash code of the Point
structure used in the previous examples.
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
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
Remarques
Un code de hachage est une valeur numérique utilisée pour insérer et identifier un objet dans une collection basée sur le hachage, telle que la classe Dictionary<TKey,TValue>, la classe Hashtable ou un type dérivé de la classe DictionaryBase.A hash code is a numeric value that is used to insert and identify an object in a hash-based collection such as the Dictionary<TKey,TValue> class, the Hashtable class, or a type derived from the DictionaryBase class. La méthode GetHashCode fournit ce code de hachage pour les algorithmes qui ont besoin de vérifications rapides de l’égalité des objets.The GetHashCode method provides this hash code for algorithms that need quick checks of object equality.
Notes
Pour plus d’informations sur l’utilisation des codes de hachage dans les tables de hachage et pour obtenir d’autres algorithmes de code de hachage, consultez l’entrée de la fonction de hachage dans Wikipédia.For information about how hash codes are used in hash tables and for some additional hash code algorithms, see the Hash Function entry in Wikipedia.
Deux objets qui sont identiques renvoient des codes de hachage qui sont égaux.Two objects that are equal return hash codes that are equal. Toutefois, l’inverse n’est pas vrai : les codes de hachage égaux n’impliquent pas l’égalité des objets, car différents objets (non égaux) peuvent avoir des codes de hachage identiques.However, the reverse is not true: equal hash codes do not imply object equality, because different (unequal) objects can have identical hash codes. En outre, .NET ne garantit pas l’implémentation par défaut de la méthode GetHashCode, et la valeur retournée par cette méthode peut différer entre les implémentations de .NET, telles que les différentes versions de .NET Framework et .NET Core, et les plateformes, telles que 32 bits et 64 bits plateformes.Furthermore, .NET does not guarantee the default implementation of the GetHashCode method, and the value this method returns may differ between .NET implementations, such as different versions of .NET Framework and .NET Core, and platforms, such as 32-bit and 64-bit platforms. Pour ces raisons, n’utilisez pas l’implémentation par défaut de cette méthode en tant qu’identificateur d’objet unique à des fins de hachage.For these reasons, do not use the default implementation of this method as a unique object identifier for hashing purposes. Les deux conséquences sont les suivantes :Two consequences follow from this:
Vous ne devez pas supposer que les codes de hachage égaux impliquent l’égalité entre les objets.You should not assume that equal hash codes imply object equality.
Vous ne devez jamais rendre persistant ou utiliser un code de hachage en dehors du domaine d’application dans lequel il a été créé, car le même objet peut être haché à travers des domaines d’application, des processus et des plateformes.You should never persist or use a hash code outside the application domain in which it was created, because the same object may hash across application domains, processes, and platforms.
Avertissement
Un code de hachage est destiné à une insertion et une recherche efficaces dans des collections basées sur une table de hachage.A hash code is intended for efficient insertion and lookup in collections that are based on a hash table. Un code de hachage n’est pas une valeur permanente.A hash code is not a permanent value. Pour cette raison :For this reason:
- Ne sérialisez pas les valeurs de code de hachage ou ne les stockez pas dans les bases de données.Do not serialize hash code values or store them in databases.
- N’utilisez pas le code de hachage comme clé pour récupérer un objet à partir d’une collection à clé.Do not use the hash code as the key to retrieve an object from a keyed collection.
- N’envoyez pas de codes de hachage à travers des domaines d’application ou des processus.Do not send hash codes across application domains or processes. Dans certains cas, les codes de hachage peuvent être calculés par processus ou par domaine d’application.In some cases, hash codes may be computed on a per-process or per-application domain basis.
- N’utilisez pas le code de hachage au lieu d’une valeur retournée par une fonction de hachage de chiffrement si vous avez besoin d’un hachage fort du point de vue du chiffrement.Do not use the hash code instead of a value returned by a cryptographic hashing function if you need a cryptographically strong hash. Pour les hachages de chiffrement, utilisez une classe dérivée de la classe System.Security.Cryptography.HashAlgorithm ou System.Security.Cryptography.KeyedHashAlgorithm.For cryptographic hashes, use a class derived from the System.Security.Cryptography.HashAlgorithm or System.Security.Cryptography.KeyedHashAlgorithm class.
- Ne Testez pas l’égalité des codes de hachage pour déterminer si deux objets sont égaux.Do not test for equality of hash codes to determine whether two objects are equal. (Les objets inégaux peuvent avoir des codes de hachage identiques.) Pour tester l’égalité, appelez la méthode ReferenceEquals ou Equals.(Unequal objects can have identical hash codes.) To test for equality, call the ReferenceEquals or Equals method.
La méthode GetHashCode peut être substituée par un type dérivé.The GetHashCode method can be overridden by a derived type. Si GetHashCode n’est pas substitué, les codes de hachage pour les types référence sont calculés en appelant la méthode Object.GetHashCode de la classe de base, qui calcule un code de hachage en fonction de la référence d’un objet. Pour plus d’informations, consultez RuntimeHelpers.GetHashCode.If GetHashCode is not overridden, hash codes for reference types are computed by calling the Object.GetHashCode method of the base class, which computes a hash code based on an object's reference; for more information, see RuntimeHelpers.GetHashCode. En d’autres termes, deux objets pour lesquels la méthode ReferenceEquals retourne true
ont des codes de hachage identiques.In other words, two objects for which the ReferenceEquals method returns true
have identical hash codes. Si les types valeur ne substituent pas GetHashCode, la méthode ValueType.GetHashCode de la classe de base utilise la réflexion pour calculer le code de hachage en fonction des valeurs des champs du type.If value types do not override GetHashCode, the ValueType.GetHashCode method of the base class uses reflection to compute the hash code based on the values of the type's fields. En d’autres termes, les types valeur dont les champs ont des valeurs égales ont des codes de hachage égaux.In other words, value types whose fields have equal values have equal hash codes. Pour plus d’informations sur le remplacement des GetHashCode, consultez la section « Remarques à l’héritage ».For more information about overriding GetHashCode, see the "Notes to Inheritors" section.
Avertissement
Si vous substituez la méthode GetHashCode, vous devez également substituer Equals, et vice versa.If you override the GetHashCode method, you should also override Equals, and vice versa. Si votre méthode Equals substituée retourne true
lorsque deux objets sont testés pour vérifier leur égalité, votre méthode GetHashCode substituée doit retourner la même valeur pour les deux objets.If your overridden Equals method returns true
when two objects are tested for equality, your overridden GetHashCode method must return the same value for the two objects.
Si un objet utilisé comme clé dans une table de hachage ne fournit pas une implémentation utile de GetHashCode, vous pouvez spécifier un fournisseur de code de hachage en fournissant une implémentation de IEqualityComparer à l’une des surcharges du constructeur de classe Hashtable.If an object that is used as a key in a hash table does not provide a useful implementation of GetHashCode, you can specify a hash code provider by supplying an IEqualityComparer implementation to one of the overloads of the Hashtable class constructor.
Notes pour le Windows RuntimeWindows RuntimeNotes for the Windows RuntimeWindows Runtime
Quand vous appelez la méthode GetHashCode sur une classe du Windows RuntimeWindows Runtime, elle fournit le comportement par défaut pour les classes qui ne substituent pas GetHashCode.When you call the GetHashCode method on a class in the Windows RuntimeWindows Runtime, it provides the default behavior for classes that don't override GetHashCode. Cela fait partie de la prise en charge fournie par le .NET Framework pour le Windows RuntimeWindows Runtime (consultez .NET Framework prise en charge des applications et des Windows Runtime du Windows Store).This is part of the support that the .NET Framework provides for the Windows RuntimeWindows Runtime (see .NET Framework Support for Windows Store Apps and Windows Runtime). Les classes du Windows RuntimeWindows Runtime n’héritent pas Objectet n’implémentent actuellement pas de GetHashCode.Classes in the Windows RuntimeWindows Runtime don't inherit Object, and currently don't implement a GetHashCode. Toutefois, ils semblent avoir des méthodes ToString, Equals(Object)et GetHashCode lorsque vous les utilisez dans votre C# code ou Visual Basic, et le .NET Framework fournit le comportement par défaut pour ces méthodes.However, they appear to have ToString, Equals(Object), and GetHashCode methods when you use them in your C# or Visual Basic code, and the .NET Framework provides the default behavior for these methods.
Notes
Windows RuntimeWindows Runtime les classes écrites dans C# ou Visual Basic peuvent substituer la méthode GetHashCode.classes that are written in C# or Visual Basic can override the GetHashCode method.
Notes pour les héritiers
Une fonction de hachage est utilisée pour générer rapidement un nombre (code de hachage) qui correspond à la valeur d’un objet.A hash function is used to quickly generate a number (hash code) that corresponds to the value of an object. Les fonctions de hachage sont généralement spécifiques à chaque type et, pour l’unicité, doivent utiliser au moins l’un des champs d’instance comme entrée.Hash functions are usually specific to each type and, for uniqueness, must use at least one of the instance fields as input. Les codes de hachage ne doivent pas être calculés à l’aide des valeurs des champs statiques.Hash codes should not be computed by using the values of static fields.
Pour les classes dérivées de Object, la méthode GetHashCode
peut déléguer à l’implémentation de la classe de base GetHashCode() uniquement si la classe dérivée définit l’égalité comme étant l’égalité des références.For classes derived from Object, the GetHashCode
method can delegate to the base class GetHashCode() implementation only if the derived class defines equality to be reference equality. L’implémentation par défaut de GetHashCode() pour les types référence retourne un code de hachage équivalent à celui retourné par la méthode GetHashCode(Object).The default implementation of GetHashCode() for reference types returns a hash code that is equivalent to the one returned by the GetHashCode(Object) method. Vous pouvez substituer GetHashCode() pour les types de référence immuables.You can override GetHashCode() for immutable reference types. En général, pour les types référence mutables, vous devez substituer GetHashCode() uniquement si :In general, for mutable reference types, you should override GetHashCode() only if:
-Vous pouvez calculer le code de hachage à partir de champs qui ne sont pas mutables ; ni- You can compute the hash code from fields that are not mutable; or
-Vous pouvez vous assurer que le code de hachage d’un objet mutable ne change pas lorsque l’objet est contenu dans une collection qui repose sur son code de hachage.- You can ensure that the hash code of a mutable object does not change while the object is contained in a collection that relies on its hash code.
Dans le cas contraire, vous pourriez penser que l’objet mutable est perdu dans la table de hachage.Otherwise, you might think that the mutable object is lost in the hash table. Si vous choisissez de remplacer GetHashCode() pour un type référence mutable, votre documentation doit indiquer clairement que les utilisateurs de votre type ne doivent pas modifier les valeurs d’objet lorsque l’objet est stocké dans une table de hachage.If you do choose to override GetHashCode() for a mutable reference type, your documentation should make it clear that users of your type should not modify object values while the object is stored in a hash table.
Pour les types de valeur, GetHashCode() fournit une implémentation de code de hachage par défaut qui utilise la réflexion.For value types, GetHashCode() provides a default hash code implementation that uses reflection. Vous devez envisager de la remplacer pour obtenir de meilleures performances.You should consider overriding it for better performance.
Pour obtenir plus d’informations et des exemples qui calculent des codes de hachage de différentes manières, consultez la section exemples.For more information and examples that compute hash codes in a variety of ways, see the Examples section.