System.Runtime.CompilerServices.RuntimeHelpers.GetHashCode-metoden

Anmärkning

Den här artikeln innehåller ytterligare kommentarer till referensdokumentationen för det här API:et.

Metoden RuntimeHelpers.GetHashCode anropar Object.GetHashCode alltid metoden icke-virtuellt, även om objektets typ har åsidosatt Object.GetHashCode metoden. Därför kan användningen RuntimeHelpers.GetHashCode skilja sig från att anropa GetHashCode direkt på objektet med Object.GetHashCode -metoden.

Varning

RuntimeHelpers.GetHashCode Även om metoden returnerar identiska hash-koder för identiska objektreferenser bör du inte använda den här metoden för att testa objektidentitet, eftersom den här hash-koden inte unikt identifierar en objektreferens. Om du vill testa objektidentiteten (det vill säga för att testa att två objekt refererar till samma objekt i minnet) anropar du Object.ReferenceEquals metoden. Du bör inte heller använda GetHashCode för att testa om två strängar representerar samma objektreferenser, eftersom strängen är internerad. Anropa String.IsInterned-metoden för att testa stränginternering.

Metoderna Object.GetHashCode och RuntimeHelpers.GetHashCode skiljer sig åt enligt följande:

  • Object.GetHashCode returnerar en hash-kod som baseras på objektets definition av likhet. Två strängar med identiskt innehåll returnerar till exempel samma värde för Object.GetHashCode.
  • RuntimeHelpers.GetHashCode returnerar en hash-kod som anger objektidentitet. Det innebär att två strängvariabler vars innehåll är identiskt och som representerar en sträng som är internerad (se avsnittet Stränginterning) eller som representerar en enda sträng i minnet och därmed returnerar identiska hashkoder.

Viktigt!

Observera att GetHashCode alltid returnerar identiska hash-koder för samma objektreferenser. Det omvända är dock inte sant: lika med hash-koder anger inte lika med objektreferenser. Ett visst hashkodvärde är inte unikt för en viss objektreferens. olika objektreferenser kan generera identiska hash-koder.

Den här metoden används av kompilatorer.

Stränginternering

CLR (Common Language Runtime) har en intern pool med strängar och lagrar literaler i poolen. Om två strängar (till exempel str1 och str2) bildas från en identisk strängliteral, kommer CLR att se till att str1 och str2 pekar på samma plats i den hanterade högen för att spara minne. Om du anropar RuntimeHelpers.GetHashCode dessa två strängobjekt skapas samma hash-kod, i motsats till det andra punktobjektet i föregående avsnitt.

CLR lägger bara till literaler i poolen. Resultat av strängoperationer, som exempelvis sammanfogning, läggs inte till i poolen om inte kompilatorn löser strängsammanfogningen som en enda strängliteral. Därför, om str2 skapades som ett resultat av en sammanfogningsåtgärd och str2 är identisk med str1, kommer användning av RuntimeHelpers.GetHashCode på dessa två strängobjekt inte att generera samma hash-kod.

Om du uttryckligen vill lägga till en sammanfogad sträng i poolen använder du String.Intern metoden .

Du kan också använda String.IsInterned metoden för att kontrollera om en sträng har en intern referens.

Exempel

I följande exempel visas skillnaden mellan Object.GetHashCode metoderna och RuntimeHelpers.GetHashCode . Utdata från exemplet illustrerar följande:

  • Båda uppsättningarna med hash-koder för den första uppsättningen strängar som skickas till ShowHashCodes metoden skiljer sig, eftersom strängarna är helt olika.

  • Object.GetHashCode genererar samma hash-kod för den andra uppsättningen strängar som skickas till ShowHashCodes metoden, eftersom strängarna är lika. Metoden gör dock RuntimeHelpers.GetHashCode inte det. Den första strängen definieras med hjälp av en strängliteral och är därför lagrad i minnet. Även om värdet för den andra strängen är detsamma, är det inte internerat eftersom det returneras av ett anrop till String.Format metoden.

  • När det gäller den tredje strängen är hash-koderna som skapas av Object.GetHashCode för båda strängarna identiska, liksom de hash-koder som skapas av RuntimeHelpers.GetHashCode. Det beror på att kompilatorn har behandlat värdet som tilldelats båda strängarna som en strängliteral, och därför refererar strängvariablerna till samma internerade sträng.

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