Methode System.Runtime.CompilerServices.RuntimeHelpers.GetHashCode

Opmerking

In dit artikel vindt u aanvullende opmerkingen in de referentiedocumentatie voor deze API.

De RuntimeHelpers.GetHashCode methode roept altijd de Object.GetHashCode methode niet-virtueel aan, zelfs als het type van het object de Object.GetHashCode methode heeft overschreven. Daarom kan het gebruik van RuntimeHelpers.GetHashCode verschillen van het rechtstreeks aanroepen van GetHashCode op het object met de methode Object.GetHashCode.

Waarschuwing

Hoewel de RuntimeHelpers.GetHashCode methode identieke hashcodes retourneert voor identieke objectverwijzingen, moet u deze methode niet gebruiken om te testen op objectidentiteit, omdat deze hashcode geen unieke identificatie van een objectverwijzing is. Als u wilt testen op objectidentiteit (om te testen of twee objecten verwijzen naar hetzelfde object in het geheugen), roept u de Object.ReferenceEquals methode aan. U moet ook niet GetHashCode gebruiken om te testen of twee strings gelijke objectverwijzingen representeren, omdat de string geïnterneerd is. Als u wilt testen op het interneren van tekenreeksen, roept u de String.IsInterned methode aan.

De Object.GetHashCode en RuntimeHelpers.GetHashCode methoden verschillen als volgt:

  • Object.GetHashCode retourneert een hash-code die is gebaseerd op de definitie van gelijkheid van het object. Twee tekenreeksen met identieke inhoud retourneren bijvoorbeeld dezelfde waarde voor Object.GetHashCode.
  • RuntimeHelpers.GetHashCode retourneert een hash-code die objectidentiteit aangeeft. Dat wil gezegd: twee tekenreeksvariabelen waarvan de inhoud identiek is en die een tekenreeks vertegenwoordigen die is geïnterneerd (zie de sectie String Interning ) of die één tekenreeks in het geheugen identieke hash-codes retourneren.

Belangrijk

Houd er rekening mee dat GetHashCode altijd identieke hashcodes worden geretourneerd voor gelijke objectverwijzingen. Het omgekeerde is echter niet waar: gelijke hashcodes geven geen gelijke objectverwijzingen aan. Een bepaalde hashcodewaarde is niet uniek voor een bepaald objectverwijzing; verschillende objectverwijzingen kunnen identieke hashcodes genereren.

Deze methode wordt gebruikt door compilers.

Tekenreeks interneren

De Common Language Runtime (CLR) onderhoudt een interne pool met tekenreeksen en slaat letterlijke waarden op in de pool. Als twee tekenreeksen (bijvoorbeeld str1 en str2) zijn afgeleid van een identieke letterlijke tekenreeks, zal de CLR str1 en str2 laten verwijzen naar dezelfde locatie op de beheerde heap om geheugen te besparen. Als u deze twee tekenreeksobjecten aanroept RuntimeHelpers.GetHashCode , wordt dezelfde hashcode geproduceerd, in tegenstelling tot het tweede item met opsommingstekens in de vorige sectie.

De CLR voegt alleen letterlijke gegevens toe aan de pool. Resultaten van tekenreeksbewerkingen, zoals samenvoeging, worden niet toegevoegd aan de pool, tenzij de compiler de tekenreekssamenvoeging oplost als één letterlijke tekenreeks. Daarom, als str2 werd gemaakt als het resultaat van een samenvoegingsbewerking en str2 identiek is aan str1, zal het gebruik van RuntimeHelpers.GetHashCode op deze twee tekenreeksobjecten niet dezelfde hash-code opleveren.

Als u een samengevoegde tekenreeks expliciet aan de pool wilt toevoegen, gebruikt u de String.Intern methode.

U kunt ook de String.IsInterned methode gebruiken om te controleren of een tekenreeks een interne verwijzing heeft.

Voorbeelden

In het volgende voorbeeld ziet u het verschil tussen de Object.GetHashCode en RuntimeHelpers.GetHashCode methoden. De uitvoer uit het voorbeeld illustreert het volgende:

  • Beide sets hash-codes voor de eerste set tekenreeksen die aan de ShowHashCodes methode worden doorgegeven, zijn verschillend, omdat de tekenreeksen volledig anders zijn.

  • Object.GetHashCode genereert dezelfde hash-code voor de tweede set tekenreeksen die aan de ShowHashCodes methode zijn doorgegeven, omdat de tekenreeksen gelijk zijn. De RuntimeHelpers.GetHashCode methode doet dit echter niet. De eerste tekenreeks wordt gedefinieerd met behulp van een letterlijke tekenreeks en wordt dus opgeslagen in het interne geheugen. Hoewel de waarde van de tweede tekenreeks hetzelfde is, wordt deze niet geïnterneerd, omdat deze wordt geretourneerd door een aanroep naar de String.Format methode.

  • In het geval van de derde tekenreeks zijn de hashcodes die door Object.GetHashCode voor beide tekenreeksen worden geproduceerd, identiek, net zoals de hashcodes die door RuntimeHelpers.GetHashCode worden geproduceerd. Dit komt doordat de compiler de waarde heeft behandeld die is toegewezen aan beide tekenreeksen als één letterlijke tekenreeks, en dus verwijzen de tekenreeksvariabelen naar dezelfde interne tekenreeks.

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