none
Como implementar IEquatable corretamente? RRS feed

  • Pergunta

  • Quando eu implemento a interface IEquatable na classe Employee, mas comparo as instancias retorna o valor true, isto esta correto pois quando eu implemento método equals eu comparo os valores de Account e não as instâncias.

    Ex:

    Employee emp12 = new Employee("GEVE", "Geert Verhoeven");
    Employee emp13 = new Employee("GEVE", "Geert Verhoeven");
    bool compara = emp12.Equals(emp13); == TRUE

    public class Employee : IEquatable<Employee>
            {
                public string Account;
                public string Name;

                public Employee(string account, string name)
                {
                    this.Account = account;
                    this.Name = name;
                }

                public bool Equals(Employee other)
                {
                    if (other == null) return false;
                    return (this.Account.Equals(other.Account));
                }
            }

    Mas quando eu uso o metodo EQUALS nativo de outra classe sem herdar a interface IEquatable,  ele me retorna false "o que seria mais correto".

    Ou seja eu não posso implementar a interface IEquatable para que eu "veja" se as instâncias são diferentes ?

    Se sim como faço isso?

    Obrigado.

               

    quarta-feira, 17 de outubro de 2012 02:32

Respostas

  • Amigo, bom dia

    obrigatoriamente você não precisa implementar nenhuma interface para isto

    faça assim que também funciona:

        public class Employee
        {
            public Employee(string _Account, string _Name)
            {
                this.Account = _Account;
                this.Name = _Name;
            }
    
            public string Account { get; set; }
            public string Name { get; set; }
    
            public override int GetHashCode()
            {
                return this.Account.GetHashCode() + this.Name.GetHashCode();
            }
    
            public override bool Equals(object obj)
            {
                Employee emp = (Employee)obj;
    
                return ((this.Account.Equals(emp.Account)) && (this.Name.Equals(emp.Name)));
            }
        }


    Olavo Oliveira Neto
    http://olavooneto.wordpress.com
    Twitter @Olavooneto
    Facebook Olavo Neto
    Linkedin Olavo Neto
    Se for útil marque como resposta e faça um Developer feliz :)

    • Marcado como Resposta Tulio S quinta-feira, 18 de outubro de 2012 14:24
    quarta-feira, 17 de outubro de 2012 12:04
    Moderador
  • A comparação entre as instancias usando do método Equals() é feita pelo HashCode do objeto por padrão, toda instancia de um objeto possui HashCode, a não ser que você atribua o mesmo objeto na nova instancia. Por exemplo:

    object o1 = new object();
    object o2 = new object();
    
    //False
    Console.WriteLine(o2.Equals(o1));
    Console.WriteLine(string.Format("o1 = {0} - o2 = {1}", o1.GetHashCode(), o2.GetHashCode()));
    
    //Atribuindo instancia do objeto o1 no objeto o2
    o2 = o1;
    
    //True
    Console.WriteLine(o2.Equals(o1));
    Console.WriteLine(string.Format("o1 = {0} - o2 = {1}", o1.GetHashCode(), o2.GetHashCode()));
    
    Console.Read();

    A ideia de implementar interfaces para comparação de objetos é justamento para o método Equals não trabalhar com a comparação de HashCode, mais sim sua comparação customizada.

    Vitor Mendes | Seu feedback é muito importante para todos!
    Visite o meu site: http://www.vitormendes.com.br/

    • Sugerido como Resposta Danimar Ribeiro quinta-feira, 18 de outubro de 2012 01:52
    • Marcado como Resposta Tulio S quinta-feira, 18 de outubro de 2012 14:08
    quarta-feira, 17 de outubro de 2012 18:52

Todas as Respostas

  • Amigo, bom dia

    obrigatoriamente você não precisa implementar nenhuma interface para isto

    faça assim que também funciona:

        public class Employee
        {
            public Employee(string _Account, string _Name)
            {
                this.Account = _Account;
                this.Name = _Name;
            }
    
            public string Account { get; set; }
            public string Name { get; set; }
    
            public override int GetHashCode()
            {
                return this.Account.GetHashCode() + this.Name.GetHashCode();
            }
    
            public override bool Equals(object obj)
            {
                Employee emp = (Employee)obj;
    
                return ((this.Account.Equals(emp.Account)) && (this.Name.Equals(emp.Name)));
            }
        }


    Olavo Oliveira Neto
    http://olavooneto.wordpress.com
    Twitter @Olavooneto
    Facebook Olavo Neto
    Linkedin Olavo Neto
    Se for útil marque como resposta e faça um Developer feliz :)

    • Marcado como Resposta Tulio S quinta-feira, 18 de outubro de 2012 14:24
    quarta-feira, 17 de outubro de 2012 12:04
    Moderador
  • Olavo,

    Obrigado mas não sei se me expressei mal, mas a dúvida não foi bem essa.

    Se eu comparar essas duas instâncias o resultado vai ser true, como no exemplo que foi implementado por mim e como no exemplo que foi implementado por você, por que ele esta verificando os valores Account e Name.

    return ((this.Account.Equals(emp.Account)) && (this.Name.Equals(emp.Name)));

    Employee emp12 = new Employee("GEVE", "Geert Verhoeven");
    Employee emp13 = new Employee("GEVE", "Geert Verhoeven");
    bool compara = emp12.Equals(emp13); == TRUE

    Mas se eu uso o metodo EQUALS de uma classe qualquer sem implementar  a interface o resultado da comparação sera FALSE, pois são duas instâncias diferentes mesmo com os mesmo valores.

          Ex.

                User emp = new User();
                User emp2 = new User();
                bool compara = emp.Equals(emp2); == FALSE

     public class User
            {
                      
            }

    A dúvida continua,

    Eu não posso implementar a interface IEquatable  para que eu "veja" se as instâncias são diferentes ?

    Se sim como faço isso?


    • Editado Tulio S quarta-feira, 17 de outubro de 2012 13:46
    quarta-feira, 17 de outubro de 2012 13:18
  • Amigo, veja que a implementação desta interface serve para os métodos de diferenciação de coleções

    http://msdn.microsoft.com/pt-br/library/ms131187.aspx


    Olavo Oliveira Neto
    http://olavooneto.wordpress.com
    Twitter @Olavooneto
    Facebook Olavo Neto
    Linkedin Olavo Neto
    Se for útil marque como resposta e faça um Developer feliz :)

    quarta-feira, 17 de outubro de 2012 15:26
    Moderador
  • Exatamente !!!...

    Mas na implementação da interface o que esta sendo testado é a igualdade dos campos da classe e não a instância em si.

    return ((this.Account.Equals(emp.Account)) && (this.Name.Equals(emp.Name)));

    Eu quero saber como implementar esta interface para diferenciar as instâncias e não seus campos.

    Quando você instancia uma classe qualquer e usa o método EQUALS ele diferencia as instâncias e não o valor dos seus campos.

    quarta-feira, 17 de outubro de 2012 18:40
  • A comparação entre as instancias usando do método Equals() é feita pelo HashCode do objeto por padrão, toda instancia de um objeto possui HashCode, a não ser que você atribua o mesmo objeto na nova instancia. Por exemplo:

    object o1 = new object();
    object o2 = new object();
    
    //False
    Console.WriteLine(o2.Equals(o1));
    Console.WriteLine(string.Format("o1 = {0} - o2 = {1}", o1.GetHashCode(), o2.GetHashCode()));
    
    //Atribuindo instancia do objeto o1 no objeto o2
    o2 = o1;
    
    //True
    Console.WriteLine(o2.Equals(o1));
    Console.WriteLine(string.Format("o1 = {0} - o2 = {1}", o1.GetHashCode(), o2.GetHashCode()));
    
    Console.Read();

    A ideia de implementar interfaces para comparação de objetos é justamento para o método Equals não trabalhar com a comparação de HashCode, mais sim sua comparação customizada.

    Vitor Mendes | Seu feedback é muito importante para todos!
    Visite o meu site: http://www.vitormendes.com.br/

    • Sugerido como Resposta Danimar Ribeiro quinta-feira, 18 de outubro de 2012 01:52
    • Marcado como Resposta Tulio S quinta-feira, 18 de outubro de 2012 14:08
    quarta-feira, 17 de outubro de 2012 18:52
  • Ok, agora entendi !!!

    Obrigado.

    quinta-feira, 18 de outubro de 2012 14:08