Quero que minha Food
classe seja capaz de testar sempre que for igual a outra instância de Food
. Mais tarde vou usá-lo em uma lista e quero usar seu List.Contains()
método. Devo implementar IEquatable<Food>
ou simplesmente substituir Object.Equals()
? Do MSDN:
Esse método determina a igualdade usando o comparador de igualdade padrão, conforme definido pela implementação do objeto IEquatable.Equals no método T (o tipo de valores na lista).
Então, minha próxima pergunta é: quais funções / classes da estrutura .NET fazem uso Object.Equals()
? Devo usá-lo em primeiro lugar?
Respostas:
O principal motivo é o desempenho. Quando os genéricos foram introduzidos no .NET 2.0 eles foram capazes de adicionar um monte de aulas puro, como
List<T>
,Dictionary<K,V>
,HashSet<T>
, etc. Estas estruturas fazem uso pesado deGetHashCode
eEquals
. Mas para tipos de valor, isso requer boxe.IEquatable<T>
permite que uma estrutura implemente umEquals
método fortemente tipado , para que nenhum boxe seja necessário. Desempenho muito melhor ao usar tipos de valor com coleções genéricas.Os tipos de referência não se beneficiam tanto, mas a
IEquatable<T>
implementação permite evitar uma conversão daSystem.Object
qual pode fazer diferença se for chamada com frequência.Conforme observado no blog de Jared Parson , você ainda deve implementar as substituições de objetos.
fonte
IEquatable<T>
interface faz mais do que lembrar um desenvolvedor de incluir umpublic bool Equals(T other)
membro na classe ou estrutura? A presença ou ausência da interface não faz diferença no tempo de execução. A sobrecarga deEquals
parece ser tudo o que é necessário.De acordo com o MSDN :
Portanto, parece que não há diferença funcional real entre os dois, exceto que qualquer um pode ser chamado dependendo de como a classe é usada. Do ponto de vista do desempenho, é melhor usar a versão genérica porque não há penalidade de boxe / unboxing associada a ela.
Do ponto de vista lógico, também é melhor implementar a interface. Substituir o objeto realmente não diz a ninguém que sua classe é realmente equivalente. A substituição pode ser apenas uma classe do not nothing ou uma implementação superficial. Usar a interface diz explicitamente: "Ei, isso é válido para verificação de igualdade!" É apenas um design melhor.
fonte
Estendendo o que Josh disse com um exemplo prático. +1 para Josh - eu estava prestes a escrever o mesmo na minha resposta.
Dessa forma, tenho o método Equals () reutilizável que funciona imediatamente para todas as minhas classes derivadas.
fonte
Se chamarmos
object.Equals
, isso força o boxe caro em tipos de valor. Isso é indesejável em cenários sensíveis ao desempenho. A solução é usarIEquatable<T>
.A idéia por trás
IEquatable<T>
disso é que ele fornece o mesmo resultado,object.Equals
mas mais rapidamente. A restriçãowhere T : IEquatable<T>
deve ser usada com tipos genéricos, como abaixo.caso contrário, ele se liga a
slower object.Equals()
.fonte