Nota
O acesso a esta página requer autorização. Pode tentar iniciar sessão ou alterar os diretórios.
O acesso a esta página requer autorização. Pode tentar alterar os diretórios.
Observação
Este artigo fornece observações complementares à documentação de referência para esta API.
O RuntimeHelpers.GetHashCode método sempre chama o Object.GetHashCode método não virtualmente, mesmo que o tipo do objeto tenha substituído o Object.GetHashCode método. Portanto, usar RuntimeHelpers.GetHashCode pode ser diferente de chamar diretamente o GetHashCode no objeto com o método Object.GetHashCode.
Advertência
Embora o RuntimeHelpers.GetHashCode método retorne códigos hash idênticos para referências de objeto idênticas, você não deve usar esse método para testar a identidade do objeto, porque esse código hash não identifica exclusivamente uma referência de objeto. Para testar a identidade do objeto (ou seja, para testar se dois objetos fazem referência ao mesmo objeto na memória), chame o Object.ReferenceEquals método. Também não deve usar GetHashCode para testar se duas cadeias de caracteres representam referências de objeto iguais, porque a cadeia de caracteres está internada. Para testar o internamento de strings, chame o método String.IsInterned.
Os Object.GetHashCode métodos e RuntimeHelpers.GetHashCode diferem da seguinte forma:
- Object.GetHashCode Retorna um código hash baseado na definição de igualdade do objeto. Por exemplo, duas cadeias de caracteres com conteúdo idêntico retornarão o mesmo valor para Object.GetHashCode.
- RuntimeHelpers.GetHashCode Retorna um código hash que indica a identidade do objeto. Ou seja, duas variáveis de cadeia de caracteres cujo conteúdo é idêntico e que representam uma cadeia de caracteres que está internada (consulte a seção String Interning ) ou que representam uma única cadeia de caracteres na memória retornam códigos hash idênticos.
Importante
Observe que GetHashCode sempre retorna códigos hash idênticos para referências de objeto iguais. No entanto, o inverso não é verdadeiro: códigos hash iguais não indicam referências de objeto iguais. Um determinado valor de código hash não é exclusivo para uma referência de objeto específica; Diferentes referências de objeto podem gerar códigos hash idênticos.
Este método é usado por compiladores.
Internamento de strings
O ambiente de execução comum (CLR) mantém um conjunto interno de cadeias de caracteres e armazena os literais nesse conjunto. Se duas cadeias de caracteres (por exemplo, str1 e str2) forem formadas a partir de um literal de cadeia de caracteres idêntico, o CLR definirá str1 e str2 para apontarem para o mesmo local no heap gerido para conservar memória. Ao chamar RuntimeHelpers.GetHashCode nestes dois objetos string, será produzido o mesmo código hash, contrariando o segundo item marcado na seção anterior.
O CLR adiciona apenas literais ao pool. Os resultados de operações de cadeia de caracteres, como concatenação, não são adicionados ao pool, a menos que o compilador resolva a concatenação de cadeia de caracteres como um único literal de cadeia de caracteres. Portanto, se str2 foi criado como resultado de uma operação de concatenação e str2 é idêntico ao str1, usando RuntimeHelpers.GetHashCode nesses dois objetos de cadeia de caracteres não produzirá o mesmo código hash.
Se você quiser adicionar uma cadeia de caracteres concatenada ao pool explicitamente, use o String.Intern método.
Você também pode usar o String.IsInterned método para verificar se uma cadeia de caracteres tem uma referência internada.
Exemplos
O exemplo a seguir demonstra a diferença entre os métodos Object.GetHashCode e RuntimeHelpers.GetHashCode. A saída do exemplo ilustra o seguinte:
Ambos os conjuntos de códigos hash para o primeiro conjunto de cadeias de caracteres passadas para o
ShowHashCodesmétodo são diferentes, porque as cadeias de caracteres são completamente diferentes.Object.GetHashCode gera o mesmo código hash para o segundo conjunto de cadeias de caracteres passadas para o
ShowHashCodesmétodo, porque as cadeias de caracteres são iguais. No entanto, o método RuntimeHelpers.GetHashCode não. A primeira string é definida usando uma string literal e assim é interpolada. Embora o valor da segunda cadeia de caracteres seja o mesmo, ela não é internada, porque é retornada por uma chamada para o String.Format método.No caso da terceira string, os códigos hash produzidos por Object.GetHashCode para ambas as strings são idênticos, assim como os códigos hash produzidos pela RuntimeHelpers.GetHashCode. Isso ocorre porque o compilador tratou o valor atribuído a ambas as cadeias de caracteres como um único literal de cadeia de caracteres e, portanto, as variáveis de cadeia de caracteres se referem à mesma cadeia de caracteres internada.
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