Méthode System.Runtime.CompilerServices.RuntimeHelpers.GetHashCode

Cet article vous offre des remarques complémentaires à la documentation de référence pour cette API.

La RuntimeHelpers.GetHashCode méthode appelle toujours la Object.GetHashCode méthode non virtuelle, même si le type de l’objet a remplacé la Object.GetHashCode méthode. Par conséquent, l’utilisation RuntimeHelpers.GetHashCode peut différer de l’appel GetHashCode directement sur l’objet avec la Object.GetHashCode méthode.

Avertissement

Bien que la RuntimeHelpers.GetHashCode méthode retourne des codes de hachage identiques pour les références d’objets identiques, vous ne devez pas utiliser cette méthode pour tester l’identité d’objet, car ce code de hachage n’identifie pas de manière unique une référence d’objet. Pour tester l’identité d’objet (autrement dit, pour tester que deux objets référencent le même objet en mémoire), appelez la Object.ReferenceEquals méthode. Vous ne devez pas non plus utiliser GetHashCode pour tester si deux chaînes représentent des références d’objet égales, car la chaîne est interne. Pour tester l’interne de chaîne, appelez la String.IsInterned méthode.

Les méthodes et RuntimeHelpers.GetHashCode les Object.GetHashCode méthodes diffèrent comme suit :

  • Object.GetHashCode retourne un code de hachage basé sur la définition de l’égalité de l’objet. Par exemple, deux chaînes avec un contenu identique retournent la même valeur pour Object.GetHashCode.
  • RuntimeHelpers.GetHashCode retourne un code de hachage qui indique l’identité de l’objet. Autrement dit, deux variables de chaîne dont le contenu est identique et qui représentent une chaîne interne (voir la section Interne de chaîne) ou qui représentent une seule chaîne en mémoire retourne des codes de hachage identiques.

Important

Notez que GetHashCode retourne toujours des codes de hachage identiques pour les références d’objet égales. Toutefois, l’inverse n’est pas vrai : les codes de hachage égaux n’indiquent pas de références d’objet égales. Une valeur de code de hachage particulière n’est pas unique à une référence d’objet particulière ; différentes références d’objet peuvent générer des codes de hachage identiques.

Cette méthode est utilisée par les compilateurs.

Interne de chaînes

Le Common Language Runtime (CLR) gère un pool interne de chaînes et stocke des littéraux dans le pool. Si deux chaînes (par exemple, str1 et str2) sont formées à partir d’un littéral de chaîne identique, le CLR définit str1 et str2 pointe vers le même emplacement sur le tas managé pour conserver la mémoire. L’appel RuntimeHelpers.GetHashCode de ces deux objets de chaîne génère le même code de hachage, contrairement au deuxième élément à puces de la section précédente.

Le CLR ajoute uniquement des littéraux au pool. Les résultats des opérations de chaîne telles que la concaténation ne sont pas ajoutés au pool, sauf si le compilateur résout la concaténation de chaîne en tant que littéral de chaîne unique. Par conséquent, si str2 elle a été créée à la suite d’une opération de concaténation et str2 est identique à str1celle RuntimeHelpers.GetHashCode utilisée sur ces deux objets de chaîne, elle ne produit pas le même code de hachage.

Si vous souhaitez ajouter explicitement une chaîne concaténée au pool, utilisez la String.Intern méthode.

Vous pouvez également utiliser la String.IsInterned méthode pour case activée si une chaîne a une référence interne.

Exemples

L’exemple suivant illustre la différence entre les méthodes et RuntimeHelpers.GetHashCode les Object.GetHashCode méthodes. La sortie de l’exemple illustre les éléments suivants :

  • Les deux ensembles de codes de hachage pour le premier ensemble de chaînes passées à la ShowHashCodes méthode sont différents, car les chaînes sont complètement différentes.

  • Object.GetHashCode génère le même code de hachage pour le deuxième jeu de chaînes passées à la ShowHashCodes méthode, car les chaînes sont égales. Toutefois, la méthode ne le RuntimeHelpers.GetHashCode fait pas. La première chaîne est définie à l’aide d’un littéral de chaîne et est donc interne. Bien que la valeur de la deuxième chaîne soit la même, elle n’est pas interne, car elle est retournée par un appel à la String.Format méthode.

  • Dans le cas de la troisième chaîne, les codes de hachage produits par Object.GetHashCode les deux chaînes sont identiques, comme les codes de hachage produits par RuntimeHelpers.GetHashCode. Cela est dû au fait que le compilateur a traité la valeur affectée aux deux chaînes comme un littéral de chaîne unique, et donc les variables de chaîne font référence à la même chaîne interne.

using System;
using System.Runtime.CompilerServices;

public class Example
{
   public static void Main()
   {
      Console.WriteLine("{0,-18} {1,6} {2,18:N0}    {3,6} {4,18:N0}\n",
                        "", "Var 1", "Hash Code", "Var 2", "Hash Code");
      
      // Get hash codes of two different strings.
      String sc1 = "String #1";
      String sc2 = "String #2";
      ShowHashCodes("sc1", sc1, "sc2", sc2);
 
      // Get hash codes of two identical non-interned strings.
      String s1 = "This string";
      String s2 = String.Format("{0} {1}", "This", "string");
      ShowHashCodes("s1", s1, "s2", s2);

      // Get hash codes of two (evidently concatenated) strings.
      String si1 = "This is a string!";
      String si2 = "This " + "is " + "a " + "string!";
      ShowHashCodes("si1", si1, "si2", si2);
   }

   private static void ShowHashCodes(String var1, Object value1, 
                                     String var2, Object value2)
   {
      Console.WriteLine("{0,-18} {1,6} {2,18:X8}    {3,6} {4,18:X8}",
                        "Obj.GetHashCode", var1, value1.GetHashCode(),
                        var2, value2.GetHashCode());

      Console.WriteLine("{0,-18} {1,6} {2,18:X8}    {3,6} {4,18:X8}\n",
                        "RTH.GetHashCode", var1, RuntimeHelpers.GetHashCode(value1),
                        var2, RuntimeHelpers.GetHashCode(value2));
   }
}
// The example displays output similar to the following:
//                        Var 1          Hash Code     Var 2          Hash Code
//    
//    Obj.GetHashCode       sc1           94EABD27       sc2           94EABD24
//    RTH.GetHashCode       sc1           02BF8098       sc2           00BB8560
//    
//    Obj.GetHashCode        s1           29C5A397        s2           29C5A397
//    RTH.GetHashCode        s1           0297B065        s2           03553390
//    
//    Obj.GetHashCode       si1           941BCEA5       si2           941BCEA5
//    RTH.GetHashCode       si1           01FED012       si2           01FED012
Imports System.Runtime.CompilerServices

Module Example
   Public Sub Main()
      Console.WriteLine("{0,-18} {1,6} {2,18:N0}    {3,6} {4,18:N0}",
                        "", "Var 1", "Hash Code", "Var 2", "Hash Code")
      Console.WriteLine()
      
      ' Get hash codes of two different strings.
      Dim sc1 As String = "String #1"
      Dim sc2 As String = "String #2"
      ShowHashCodes("sc1", sc1, "sc2", sc2)
 
      ' Get hash codes of two identical non-interned strings.
      Dim s1 As String = "This string"
      Dim s2 As String = String.Format("{0} {1}", "This", "string")
      ShowHashCodes("s1", s1, "s2", s2)

      ' Get hash codes of two (evidently concatenated) strings.
      Dim si1 As String = "This is a string!"
      Dim si2 As String = "This " + "is " + "a " + "string!"
      ShowHashCodes("si1", si1, "si2", si2)
   End Sub
   
   Private Sub ShowHashCodes(var1 As String, value1 As Object, 
                             var2 As String, value2 As Object)
      Console.WriteLine("{0,-18} {1,6} {2,18:X8}    {3,6} {4,18:X8}",
                        "Obj.GetHashCode", var1, value1.GetHashCode,
                        var2, value2.GetHashCode)

      Console.WriteLine("{0,-18} {1,6} {2,18:X8}    {3,6} {4,18:X8}",
                        "RTH.GetHashCode", var1, RuntimeHelpers.GetHashCode(value1),
                        var2, RuntimeHelpers.GetHashCode(value2))
      Console.WriteLine()
   End Sub
End Module
' The example displays output similar to the following:
'                        Var 1          Hash Code     Var 2          Hash Code
'    
'    Obj.GetHashCode       sc1           94EABD27       sc2           94EABD24
'    RTH.GetHashCode       sc1           02BF8098       sc2           00BB8560
'    
'    Obj.GetHashCode        s1           29C5A397        s2           29C5A397
'    RTH.GetHashCode        s1           0297B065        s2           03553390
'    
'    Obj.GetHashCode       si1           941BCEA5       si2           941BCEA5
'    RTH.GetHashCode       si1           01FED012       si2           01FED012