Pergunta

ver também Hows para verificação rápida se os dados transferir dois objetos têm o mesmo propriedades em C #?

Eu tenho muita Transferência Data Objects (DTO) que cada um contém lotes de campos simples . Eu preciso implementar Equals em todos eles (para que eu possa escrever alguns testes de unidade off transportá-los var WCF).

O código que estou usando é:

public override bool Equals(object rhs)
{

    RequestArguments other = rhs as RequestArguments;

    return
       other != null && 
       other.m_RequestId.Equals(RequestId) && 
       other.m_Type.Equals(m_Type) && 
       other.m_Parameters.Equals(m_Parameters) && 
       other.m_user.Equals(m_user);
}

Deve haver uma maneira melhor! ... (listando todos os campos é bastante pedindo erros e problemas de manutenção)

por exemplo. temos objeto. MemberwiseClone () para ajudar com o caso Clonagem (), mas eu não consigo encontrar nada para ajudar com Equals. Estamos executando em confiança total para que uma solução baseada reflexão é uma resposta, mas eu prefiro não reinventar a roda.

(Desculpe, mas não gerar o DTO a partir de uma linguagem específica de domínio de outra forma esse tipo de coisa seria fácil! Também eu não sou capaz de mudar o sistema de compilação para adicionar mais um passo)

Foi útil?

Solução

Engraçado você perguntar, eu recentemente publicado algum código para fazer exatamente isso. Confira o meu MemberwiseEqualityComparer para ver se ele se adapta às suas necessidades.

É muito fácil de usar e bastante eficiente também. Ele usa IL-emita para gerar os Iguais inteiras e função GetHashCode na primeira execução (uma vez para cada tipo usado). Ele irá comparar cada campo (privada ou pública) do objeto determinado usando o comparador de igualdade padrão para esse tipo (EqualityComparer.Default). Temos vindo a usá-lo em produção por um tempo e parece estável, mas eu vou deixar nenhuma garantia =)

Ela cuida de todos os Edge-casos os pescy que raramente pensa quando você está rolando o seu próprio método equals (ou seja, você não pode comparer seu próprio objeto com nulo, a menos que você tenha em caixa-lo em um objeto primeiro e lote está fora mais problemas nulos-relacionada).

Eu estive significado para escrever um post sobre isso, mas não tivemos tempo para isso ainda. O código é um pouco situação irregular, mas se você como se eu pudesse limpá-lo um pouco.

public override int GetHashCode()
{
    return MemberwiseEqualityComparer<Foo>.Default.GetHashCode(this);
}

public override bool Equals(object obj)
{
    if (obj == null)
        return false;

    return Equals(obj as Foo);
}

public override bool Equals(Foo other)
{
    return MemberwiseEqualityComparer<Foo>.Default.Equals(this, other);
}

O MemberwiseEqualityComparer é liberado sob a MIT licença meaining você pode fazer praticamente o que quiser com ele, incluindo usá-lo em soluções proprietárias, sem alterar-lhe licenciar um pouco.

Outras dicas

Uma opção é usar o reflexo para obter todos os campos disponíveis e, em seguida, obter e comparar os seus valores sobre os objetos desejados. Isto lhe daria uma solução genérica, mas você teria bastante trabalho a fazer, provavelmente usando hashes como Alex sugere é uma solução mais limpa.

Editar : Aqui está um exemplo simples de comparar objetos usando reflexão, ele olha para propriedades em vez de campos, mas você começa a idéia: http://www.willasrari.com/blog/use-systemreflection-for-comparing-custom-objects/ 000257.aspx

Você pode ter um conceito de um hash objeto - sempre que um objeto muda, você paga o preço de atualizar o hash (onde o hash é, literalmente, um hash de todas as propriedades concatenadas). Então, se você tem um monte de objetos que raramente mudam, é realmente barato para compará-los. O preço, é claro, é pago no momento objeto edição.

Editar : desculpe, eu não notei que você está pedindo para o teste de serialização. Portanto, esta abordagem definitivamente não funciona para você.


Não há outra maneira "suja". Se o objeto é de qualquer maneira serializado, você pode serialize -los e comparar os fluxos resultantes.

Este é um pouco lento, mas deve ser bastante confiável e fácil de implementar.

Estamos fazendo isso algumas vezes para verificar se alguém mudou todos os dados em um editor.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top