C# - Apresentando o método GetHashCode


 Hoje vamos apresentar o método GetHashCode, o que ele faz, como atua e porque ele é importante.

O método GetHashCode() é um método de Object que é herdado por todos os objetos na linguagem C#.
Este método basicamente serve como função de hash padrão.

Mas o que é hash ???

Um código hash é um valor numérico que é usado para inserir e identificar um objeto
em uma coleção baseada em hash, como a classe Dictionary<Key,Value>, a classe
HashTable ou um tipo derivado da classe DictionaryBase classe.

O método GetHashCode fornece esse código hash para algoritmos que necessitam realizar verificações rápidas de igualdade em objetos.

Assim este método é usado para comparar objetos por valor.

Dois objetos que são iguais vão retornar um código hash igual, mas dois códigos hash iguais não implicam que os objetos sejam iguais,  porque objetos diferentes podem possuir um código hash igual.

Nota: A plataforma .NET não garante a implementação padrão do método GetHashCode, e o valor que esse método retorna pode ser diferente entre as implementações do .NET, como versões diferentes do .NET Framework e .NET Core, e plataformas, como 32 bits e  Plataformas de 64 bits. Por isso, você não deve usar a implementação padrão desse método como um identificador de objeto exclusivo  para fins de hash.

Assim você deve estar atento para as seguintes implicações:

  1. Não assuma que dois códigos hash iguais implicam em igualdade de objeto;
  2. Não use ou persista um código hash fora do domínio do aplicativo no qual foi criado, pois o mesmo objeto pode fazer hash em domínios de aplicativo, processos e plataformas;

O método GetHashCode pode ser substituído por um tipo derivado; se ele não for substituído então :

Assim, dois objetos para os quais o método ReferenceEquals retornam true possuem códigos hash idênticos.

E os tipos por valor ?

Se nos tipos de valor não houver a substituição do método GetHashCode, então  :

Portanto, os tipos de valor cujos membros têm valores iguais possuem códigos hash iguais.

Agora, se você substituir(override) o método GetHashCode, também deverá substituir o método Equals e vice-versa, e, se o método Equals substituído retornar true quando dois objetos forem testados quanto à igualdade, o método GetHashCode substituído deverá retornar o mesmo valor para os dois objetos.

Gerando substituições para os métodos Equals e GetHashCode no VS 2019

O VS 2019 Community permite gerar de forma automática os métodos Equals e GetHashCode.

Vamos supor que temos uma classe Demo com duas propriedades Numero e Resultado e que precisamos comparar objetos deste tipo por valor e não por referência.

    public class Demo
    {
        public double Numero { get; set; }
        public double Resultado { get; set; }
    }

Para gerar os métodos GetHashCode e Equals faça o seguinte:

       

Veja abaixo o fluxo completo realizado no VS 2019 Community:

       

using System;
namespace C_GetHashCode_Equals
{
    public class Demo
    {
        public double Numero { get; set; }
        public double Resultado { get; set; }
        public override bool Equals(object obj)
        {
            return obj is Demo demo &&
                   Numero == demo.Numero &&
                   Resultado == demo.Resultado;
        }
        public override int GetHashCode()
        {
            return HashCode.Combine(Numero, Resultado);
        }
    }
}

Note que na caixa Pick Members você tem a opção de gerar os operadores para a classe marcando o item :
Generate operators

Serão gerados também as sobrecargas dos operadores == e !=.

E estamos conversados...

E a vida eterna é esta: que te conheçam a ti, o único Deus verdadeiro, e a Jesus Cristo, a quem enviaste.
João 17:3

Referências:


José Carlos Macoratti