Poznámka
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Tento článek obsahuje doplňující poznámky k referenční dokumentaci pro toto rozhraní API.
Metoda RuntimeHelpers.GetHashCode vždy volá metodu Object.GetHashCode ne-virtualně, i když typ objektu přepsal metodu Object.GetHashCode . Proto se použití RuntimeHelpers.GetHashCode může lišit od volání GetHashCode
přímo na objektu s metodou Object.GetHashCode.
Výstraha
I když metoda RuntimeHelpers.GetHashCode vrací identické hashové kódy pro identické odkazy na objekty, neměli byste tuto metodu použít k testování identity objektu, protože tento kód hash jednoznačně neidentifikuje odkaz na objekt. Chcete-li otestovat identitu objektu (to znamená otestovat, že dva objekty odkazují na stejný objekt v paměti), zavolejte metodu Object.ReferenceEquals . Neměli byste ani použít GetHashCode pro testování, zda dva řetězce představují stejné odkazy na objekt, protože řetězec je internovaný. Pokud chcete otestovat prokládání řetězců, zavolejte metodu String.IsInterned .
Tyto metody Object.GetHashCode a RuntimeHelpers.GetHashCode se liší následujícím způsobem:
- Object.GetHashCode vrátí hashovací kód, který je založen na definici objektu rovnosti. Například dva řetězce s identickým obsahem vrátí stejnou hodnotu pro Object.GetHashCode.
- RuntimeHelpers.GetHashCode vrátí hashovací kód, který označuje identitu objektu. To znamená, že dvě řetězcové proměnné, jejichž obsah je shodný a představují řetězec, který je interovaný (viz oddíl Prokládání řetězců ) nebo které představují jeden řetězec v paměti vrací stejné hashové kódy.
Důležité
Všimněte si, že GetHashCode vždy vrací identické hashové kódy pro odkazy na stejné objekty. Opačná hodnota však není pravdivá: kódy hash neindikují stejné odkazy na objekty. Konkrétní hodnota kódu hash není jedinečná pro konkrétní odkaz na objekt; odkazy na různé objekty mohou generovat stejné hashovací kódy.
Tuto metodu používají kompilátory.
Internování řetězců
Modul CLR (Common Language Runtime) udržuje interní zásobník řetězců a ukládá do něj literály. Pokud jsou dva řetězce (například str1
a str2
) vytvořeny z identického řetězcového literálu, CLR nastaví str1
a str2
tak, aby ukazovaly na stejné umístění ve spravované haldě, aby ušetřil paměť. Při volání RuntimeHelpers.GetHashCode na tyto dva řetězcové objekty se vytvoří stejný kód hash, na rozdíl od druhé položky s odrážkou v předchozí části.
CLR přidává do fondu jen literály. Výsledky řetězcových operací, jako je zřetězení, se do paměťového fondu nepřidávají, pokud kompilátor nevyřeší zřetězení řetězce jako jeden řetězcový literál. Proto pokud bylo str2
vytvořeno jako výsledek operace zřetězení a str2
je identický s str1
, použití RuntimeHelpers.GetHashCode u těchto dvou řetězcových objektů nevygeneruje stejný hash kód.
Pokud chcete do fondu explicitně přidat zřetězený řetězec, použijte metodu String.Intern .
Můžete také použít metodu String.IsInterned ke kontrole, zda má řetězec internovaný odkaz.
Příklady
Následující příklad ukazuje rozdíl mezi metodami Object.GetHashCode a RuntimeHelpers.GetHashCode. Výstup z příkladu ukazuje následující:
Obě sady hash kódů pro první sadu řetězců předávaných metodě
ShowHashCodes
se liší, protože řetězce jsou zcela odlišné.Object.GetHashCode vygeneruje stejný hash kód pro druhou sadu řetězců předaných metodě
ShowHashCodes
, protože řetězce jsou stejné. RuntimeHelpers.GetHashCode Metoda však nefunguje. První řetězec je definován pomocí řetězcového literálu, a proto je internován. I když je hodnota druhého řetězce stejná, není internována, protože je vrácena voláním metody String.Format.V případě třetího řetězce jsou kódy hash vytvořené Object.GetHashCode pro oba řetězce identické, stejně jako kódy hash vytvořené RuntimeHelpers.GetHashCode. Důvodem je to, že kompilátor zachází s hodnotou přiřazenou oběma řetězci jako s jedním řetězcovým literálem, a proto proměnné řetězce odkazují na stejný interovaný řetězec.
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