« Voltar
em .net c# equals object

A maneira correta de comparar objetos em C#.

Suponhamos que você tenha a seguinte classe:

public class Cliente  
{
    public int Id { get; set; }
    public string Nome { get; set; }
}

Uma classe bem simples que apenas guarda Nome e Id de um cliente.
Agora, faremos o seguinte:

Cliente c1 = new Cliente();  
c1.Nome = "Gabriel";  
c1.Id = 1;

Cliente c2 = new Cliente();  
c2.Nome = "Gabriel";  
c2.Id = 1;  

Criei dois objetos, c1 e c2, ambos do tipo Cliente e atribui um Id e Nome para eles.
Agora quero fazer o seguinte: comparar esses dois objetos e saber se eles são iguais.

Então faço:

if (c1 == c2)  
{
    //mostra mensagem falando que são iguais
}
else  
{
    //mostra mensagem falando que são diferentes
}

E aí, o que deveria acontecer aqui? Deveria mostrar que eles são iguais, certo?
Errado!

O que aconteceu?

Quando você cria c1 e c2, o cenário é o seguinte:

Smiley face

Você tem dois objetos diferentes e duas váriaveis diferentes apontando para eles: c1 e c1. Dentro dessas variáveis temos como se fosse o endereço de memória onde os objetos vivem.

Quando você faz if (c1 == c2) não está comparando o conteúdo dos objetos, mas a referência para qual as variáveis apontam.
Ou seja: está comparando e elas apontam para o mesmo objeto. E não: elas apontam para objetos diferentes!

Como eu comparo dois objetos então?

Ensinando objetos a se compararem com o Equals

Todas as classes herdam direta ou indiretamente de Object. E lá na classe Object existe um método que é herdado por todas as classes do C#: o método Equals.

E esse método Equals seria então a maneira correta de comparar objetos. Então, ao invés do if, faríamos:

if (c1.Equals(c2))  
{
    //mostra mensagem falando que são iguais
}
else  
{
    //mostra mensagem falando que são diferentes
}

Mas vai continuar falando que são diferentes!

Sobrescrevendo o Equals

Isso porque o método Equals por trás dos panos faz mesma coisa que estávamos fazendo antes com o if.
Mas tem um porém: o Equals é um método virtual! Podemos sobrescrevê-lo em nossas classes.

Vamos fazer isso então na classe Cliente:

public class Cliente  
{
    public int Id { get; set; }
    public string Nome { get; set; }
}

public override bool Equals (object o)  
{
    if (this.Id == o.Id && this.Nome == o.Nome)
    {
        return true;
    }
    else
    {
        return false;
    }
}

Veja que o que fazemos é o seguinte: o método Equals sempre vai receber um Cliente e verificamos se Nome e Id são iguais. Se forem, devolvemos true, ou seja: os objetos são iguais. Se não, devolvemos false para indicar que não são.

Mas pera: esse código não compila!
Isso porque o compilador não sabe o que tem dentro da variável o, afinal ela é o tipo object e object pode ser qualquer coisa. Precisamos antes verificar se o que tem dentro dessa variável é um Cliente e, se for, tratar ela como um Cliente fazendo um cast:

//restante da classe

public override bool Equals (object o)  
{
    if (o is Cliente)
    {
        Cliente cli = (Cliente) o;
        if (this.Id == cli.Id && this.Nome == cli.Nome)
        {
            return true;
        }
        else
        {
            return false;
        }
    }
    else
    {
        return false;
    }
}

Se o não, eu caio no else e devolvo false. Afinal, não tem como os objetos serem iguais se forem de tipos diferentes.

Podemos simplificar esse método tirando os else:

//restante da classe

public override bool Equals (object o)  
{
    if (o is Cliente)
    {
        Cliente cli = (Cliente) o;
        if (this.Id == cli.Id && this.Nome == cli.Nome)
        {
            return true;
        }
        return false;
    }
    return false;
}

Pronto!

Usando o Equals você ensina seus objetos a se compararem. E essa igualdade vai depender da sua regra de negócio: quando faz sentido pra você que dois objetos sejam iguais?

Basta decidir e implementar a comparação dentro do Equals :)


Quer ficar em dia com os meus posts e novidades?

Participe do grupo no Telegram!

Aproveite e também e inscreva na minha newsletter, me segue no Twitter e na minha página!

comments powered by Disqus