Deve IEquatable <T>, IComparable <T> ser implementado em classes não-seladas?
Alguém tem alguma opinião sobre se deve ou nãoIEquatable<T>
ouIComparable<T>
deve geralmente exigir queT
ésealed
(se é umclass
)
Esta questão me ocorreu desde que eu estou escrevendo um conjunto de classes base destinadas a auxiliar na implementação de classes imutáveis. Parte da funcionalidade que a classe base pretende fornecer é a implementação automática de comparações de igualdade (usando os campos da classe junto com atributos que podem ser aplicados a campos para controlar comparações de igualdade). Deve ser muito bom quando eu terminar - estou usando árvores de expressão para criar dinamicamente uma função de comparação compilada para cadaT
, portanto, a função de comparação deve estar muito próxima do desempenho de uma função de comparação de igualdade regular. (Eu estou usando um dicionário imutável digitadoSystem.Type
e verifique novamente o bloqueio para armazenar as funções de comparação geradas de uma maneira razoavelmente eficiente)
Uma coisa que surgiu, no entanto, é que funções usar para verificar a igualdade dos campos de membros. Minha intenção inicial era verificar se o tipo de campo de cada membro (que eu chamareiX
) implementosIEquatable<X>
. No entanto, depois de pensar um pouco, não acho que seja seguro usar a menos queX
ésealed
. A razão é que seX
não ésealed
, Eu não sei ao certo seX
está apropriadamente delegando verificações de igualdade para um método virtualX
, permitindo assim que um subtipo anule a comparação de igualdade.
Isso, então, traz uma questão mais geral - se um tipo não é selado, ele deveria realmente implementar essas interfaces? Eu acho que não, já que eu diria que o contrato de interfaces é comparar entre doisX
tipos, não dois tipos que podem ou não serX
(embora eles devam ser obviamenteX
ou um subtipo).
O que é que vocês acham? DevemosIEquatable<T>
eIComparable<T>
ser evitado para classes não seladas? (Também me faz pensar se existe uma regra fxcop para isso)
Meu pensamento atual é ter a minha função de comparação gerada apenas usarIEquatable<T>
nos campos de membros cujosT
ésealed
e, em vez disso, usar o virtualObject.Equals(Object obj)
E seT
é vedado mesmo seT
implementaIEquatable<T>
, já que o campo poderia armazenar subtipos deT
e duvido que a maioria das implementações deIEquatable<T>
são projetados adequadamente para herança.