Pergunta

Referindo-me à pergunta que fiz anteriormente:Compare duas listas que contêm muitos objetos

É impressionante ver o quão rápida essa comparação é feita com a implementação da interface IEqualityComparer: exemplo aqui

Como mencionei na minha outra pergunta, esta comparação me ajuda a fazer backup de uma pasta de origem em uma pasta de destino.Sei que quero sincronizar com pastas, portanto preciso comparar as datas dos arquivos.Sempre que faço algo como:

public class MyFileComparer2 : IEqualityComparer<MyFile>
{

    public bool Equals(MyFile s, MyFile d)
    {
        return
            s.compareName.Equals(d.compareName) &&
            s.size == d.size &&
            s.deepness == d.deepness &&
            s.dateModified.Date <= d.dateModified.Date;  // This line does not work. 
            // I also tried comparing the strings by converting it to a string and it does
            // not work. It does not give me an error but it does not seem to include the files
            // where s.dateModified.Date < d.dateModified.Date

    }

    public int GetHashCode(MyFile a)
    {
        int rt = (a.compareName.GetHashCode() * 251 + a.size.GetHashCode() * 251 + a.deepness.GetHashCode() + a.dateModified.Date.GetHashCode());

        return rt;

    }
}

Seria bom se eu pudesse fazer algo semelhante usando sinais de maior ou igual.Também tentei usar a propriedade tick e não funcionou.Talvez eu esteja fazendo algo errado.Acredito que não seja possível comparar as coisas com o sinal de menor que igual implementando esta interface.Além disso, não entendo como funciona esta classe;Só sei que é impressionante a rapidez com que ele percorre toda a lista.

Foi útil?

Solução

Como os objetos DateTime são diferentes no caso em que um DateTime é menor que o outro, você obtém códigos hash diferentes para os objetos é e d e o método Equals não é chamado.Para que a comparação das datas funcione, você deve remover a parte da data do método GetHashCode:

public int GetHashCode(MyFile a)
{
    int rt = ((a.compareName.GetHashCode() * 251 + a.size.GetHashCode())
                          * 251 + a.deepness.GetHashCode()) *251;

    return rt;

}

Outras dicas

Toda a sua abordagem é fundamentalmente falha porque o seu IEqualityComparer.Equals método não é simétrico.Isso significa Equals(file1, file2) não é igual Equals(file2, file1) por causa da maneira como você está usando o operador menor que.

A documentação:

afirma claramente:

Notas para Implementadores

O método Equals é reflexivo, simétrico e transitivo.Ou seja, retorna verdadeiro se for usado para comparar um objeto consigo mesmo;verdadeiro para dois objetos x e y se for verdadeiro para y e x;e verdadeiro para dois objetos x e z se for verdadeiro para x e y e também verdadeiro para y e z.

Implementações são necessárias para garantir que, se o método Equals retornar verdadeiro para dois objetos x e y, o valor retornado pelo método GetHashCode para x deverá ser igual ao valor retornado para y.

Em vez disso, você precisa usar o IComparable interface ou IEqualityComparer em combinação com comparações de datas.Do contrário, as coisas podem parecer funcionar por um tempo, mas você se arrependerá mais tarde.

Seu GetHashCode tem um problema:

public int GetHashCode(MyFile a)
{
    int rt = (((a.compareName.GetHashCode() * 251) 
           + a.size.GetHashCode() * 251)
           + a.deepness.GetHashCode() *251) 
           + a.dateModified.Date.GetHashCode();

    return rt;

}

Alterei a parte da data porque também precisava do tempo, portanto, uso a propriedade ticks.Eu me livrei do código hash dateModified e funciona muito bem.aqui está como modifiquei meu programa.Eu estava tendo problemas para comparar as datas, portanto usei a propriedade Ticks.

public class MyFileComparer2 : IEqualityComparer<MyFile>
{

    public bool Equals(MyFile s, MyFile d)
    {
        return
            s.compareName.Equals(d.compareName) &&
            s.size == d.size &&
            s.deepness == d.deepness &&
            //s.dateModified.Date <= d.dateModified.Date &&
            s.dateModified.Ticks >= d.dateModified.Ticks
            ;  

    }

    public int GetHashCode(MyFile a)
    {
        int rt = (((a.compareName.GetHashCode() * 251)
                + a.size.GetHashCode() * 251)
                + a.deepness.GetHashCode() * 251)
                //+ a.dateModified.Ticks.GetHashCode();                       
                ;

        return rt;

    }
}

Ainda não sei como funciona essa função de código hash.O bom é que funciona muito bem.

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