Сравните два списка, содержащих много объектов (2-я часть)

StackOverflow https://stackoverflow.com/questions/6012874

Вопрос

Возвращаясь к вопросу, который я задавал ранее:Сравните два списка, которые содержат много объектов

Впечатляет, насколько быстро выполняется это сравнение благодаря реализации интерфейса IEqualityComparer: пример здесь

Как я уже упоминал в своем другом вопросе, это сравнение помогает мне создать резервную копию исходной папки в папке назначения.Знаю, что хочу синхронизировать папки, поэтому мне нужно сравнить даты файлов.Всякий раз, когда я делаю что-то вроде:

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;

    }
}

Было бы неплохо, если бы я мог сделать что-то подобное, используя знаки «больше» или «равно».Я также пробовал использовать свойство галочки, но оно не работает.Возможно, я делаю что-то неправильно.Я считаю, что невозможно сравнивать вещи со знаком меньше, чем равно, реализующим этот интерфейс.Более того, я не понимаю, как работает этот класс;Я просто знаю, что впечатляет то, как быстро он проходит по всему списку.

Это было полезно?

Решение

Поскольку объекты DateTime отличаются в том случае, когда одно значение dateTime меньше, чем другое, вы получаете разные hashcodes для объектов s и d и метод равенстване вызывается.Для того, чтобы ваше сравнение датов на работу вы должны удалить часть даты из метода GetHashCode:

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

    return rt;

}
.

Другие советы

Весь ваш подход в корне ошибочен, потому что ваш IEqualityComparer.Equals метод не симметричен.Это означает Equals(file1, file2) не равно Equals(file2, file1) из-за того, как вы используете оператор «меньше».

Документация:

четко сказано:

Примечания для разработчиков

Метод Equals является рефлексивным, симметричным и транзитивным.То есть он возвращает true, если используется для сравнения объекта с самим собой;true для двух объектов x и y, если это верно для y и x;и истинно для двух объектов x и z, если оно верно для x и y, а также верно для y и z.

Реализации необходимы для того, чтобы гарантировать, что если метод Equals возвращает true для двух объектов x и y, то значение, возвращаемое методом GetHashCode для x, должно равняться значению, возвращаемому для y.

Вместо этого вам нужно использовать IComparable интерфейс или IEqualityComparer в сочетании со сравнением дат.Если вы этого не сделаете, какое-то время может показаться, что все работает, но позже вы пожалеете об этом.

Ваш GethashCode имеет проблему:

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;

}
.

Я изменил часть даты, потому что мне также нужно время, поэтому вместо этого я использую свойство Ticks.Я избавился от DateModified Hashed Code, и он отлично работает.Вот как я изменил мою программу.У меня возникли проблемы с сравнением дат, поэтому я использовал свойство The 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;

    }
}
.

Я до сих пор не знаю, как работает этот хэш-код функции.Приятно, что он отлично работает.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top