Kommentar
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
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
ShowHashCodesmetoden 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
ShowHashCodesmetoden, 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