Solucionado (ver solução)
Solucionado
(ver solução)
7
respostas

Método Equals() e Coleções

Boa noite!

Fiz abaixo um pequeno programa para estudar o que foi passado na aula de Coleções e percebi que sempre que o programa entra no Foreach, para adicionar os items no combobox, ele automaticamente chama o métodos Equals(object obj) herdado da classe object. (tanto faz se eu uso uma List ou um hashcode) Então, na minha classe pessoa, colaborador e visitante sobrescrevi o método Equals, conforme abaixo:

        public override bool Equals(object obj)
        {
            Pessoa pessoa = (Pessoa)obj;
            return this.Rg == pessoa.Rg;
        }

O problema é que sempre quando vai adicionar no combo box, ele está passando para o equals a referência nula. Não entendi o por quê. Alguém poderia me ajudar com essa dúvida?

        private void Form1_Load(object sender, EventArgs e)
        {
            Colaborador[] colaboradores = new Colaborador[2];
            colaboradores[0] = new Colaborador(1234,1444);
            colaboradores[0].Nome = "Fernando";
            colaboradores[0].Rg = "32293-1";

            colaboradores[1] = new Colaborador(4321, 1555);
            colaboradores[1].Nome = "Vanessa";
            colaboradores[1].Rg = "2222222-2";

            Visitante[] visitante = new Visitante[2];
            visitante[0] = new Visitante(333, colaboradores[0]);
            visitante[0].Nome = "José";
            visitante[0].Rg = "2222222-2";

            visitante[1] = new Visitante(222, colaboradores[1]);
            visitante[1].Nome = "Juca";
            visitante[1].Rg = "2222222-2";

            var pessoas = new HashSet<Pessoa>();
            pessoas.Add(colaboradores[0]);
            pessoas.Add(colaboradores[1]);
            pessoas.Add(visitante[0]);
            pessoas.Add(visitante[1]);

            foreach(Pessoa pessoa in pessoas)
            {
                cmbPessoa.Items.Add(pessoa);
                cmbPessoa.DisplayMember = "Nome";
            }
        }

Obrigado =]

7 respostas

como sabe que está vindo null? no que está dando print?

Quando faço o debug passo a passo, colocando o ponteiro em cima do FOREACH, verifico que no cmbPessoa.Items.Add(pessoa) tem o colaborador[0] "Fernando" dentro. Logo nessa linha é chamado o método equal, com object OBJ do método em branco {}. Quando vou fazer o cast, ele dá o erro abaixo:

An exception of type 'System.InvalidCastException' occurred in Testando.exe but was not handled in user code

Additional information: Não é possível converter um objeto do tipo 'System.DBNull' no tipo 'Testando.Pessoa'.

Obrigado.

Colaborador e Visitante são filhas da classe pessoa?

Ele tá dando a entender que voce ta puxando um objeto do banco e está vindo o DBNull, que não é null mas simboliza que não havia valores. Onde está havendo consulta ao banco? Nao estou vendo ai...

Opa Paulo,

Então, não tem comunicação com o banco. As classes colaborador e visitante herdam de Pessoa.

Vou compartilhar o link do meu projeto abaixo, se puder dar uma luz. Já dei uma pesquisada, mas fiquei meio sem entender o por quê do erro.

https://we.tl/m0Uk1nsFbz

Obrigado novamente.

solução!

Fala Fernando, beleza?

O problema é seu método Equals na classe Pessoa:

public override bool Equals(object obj)
{
    Pessoa pessoa = (Pessoa)obj;
     return this.Rg == pessoa.Rg;
}

Como equals recebe "object" como parâmetro pode vir QUALQUER COISA como parâmetro aí: desde uma string um e um objeto de outro tipo até "null". E em algum momento, está vindo nulo. Quando vem nulo, ele não consegue fazer o cast para pessoa na primeira linha.

O ideal em métodos que recebem object e que você precisa fazer um cast é você verificar o objeto é do tipo que você quer antes de fazer o cast. Algo como:

public override bool Equals(object obj)
{
    if(obj is Pessoa)
    {
        Pessoa pessoa = (Pessoa)obj;
        return this.Rg == pessoa.Rg;
    }
    return false;
}

Isso resolve o erro que estava dando.

Eu não vi em que momento ele chama o Equals, mas provavelmente é na hora que você está usando o HashSet para adicionar as pessoas. O HashSet usa os métodos GetHashCode e Equals para classificar os elementos dentro dele :)

O Erro foi resolvido, mas ele continua deixando eu adicionar no meu HashSet pessoas com o mesmo RG, ai todas as pessoas acabam aparecendo no meu combobox. Muito obrigado pela ajuda. Vou tentar fazer um exemplo mais simples para entender o Hashset.

abs.

Como está o seu GetHashCode? Ele deve estar espalhando errado. Como você está comparando pelo rg, seu hashcode deve ser igual para todos que tiverem o mesmo rg. A dica é, ao reescrever o hashcode, retornar entao o rg.GetHashCode