Переопределите Equals и GetHashCode, используя EqualityComparerи сравнение по элементам Списка - PullRequest
0 голосов
/ 21 января 2019

У меня есть следующие классы с переопределениями Equals и GetHashCode, автоматически сгенерированными Visual Studio (2017):

public class A
{
    public string Id { get; set; }
    public long? Total { get; set; }
    public IList<B> Bs { get; set; }

    public override bool Equals(object obj)
    {
        var a = obj as A;
        return a != null &&
               Id == a.Id &&
               EqualityComparer<long?>.Default.Equals(Total, a.Total) &&
               EqualityComparer<IList<B>>.Default.Equals(Bs, a.Bs);
    }

    public override int GetHashCode()
    {
        var hashCode = -1568924569;
        hashCode = hashCode * -1521134295 + EqualityComparer<string>.Default.GetHashCode(Id);
        hashCode = hashCode * -1521134295 + EqualityComparer<long?>.Default.GetHashCode(Total);
        hashCode = hashCode * -1521134295 + EqualityComparer<IList<B>>.Default.GetHashCode(Bs);
        return hashCode;
    }
}

public class B
{
    public string Id { get; set; }
    public long? Total { get; set; }

    public override bool Equals(object obj)
    {
        var b = obj as B;
        return b != null &&
               Id == b.Id &&
               EqualityComparer<long?>.Default.Equals(Total, b.Total);
    }

    public override int GetHashCode()
    {
        var hashCode = 716770973;
        hashCode = hashCode * -1521134295 + EqualityComparer<string>.Default.GetHashCode(Id);
        hashCode = hashCode * -1521134295 + EqualityComparer<long?>.Default.GetHashCode(Total);
        return hashCode;
    }
}

Дело в том, что список Bs возвращает false, даже если все элементы обоих списков равны в переопределении B.Equals. Я предполагаю, что это связано с тем, что EqualityComparer<IList<B>>.Default.Equals(Bs, a.Bs) сравнивает ссылку на Список, а не элементы внутри списков.

Я попытался изменить метод A.Equals на

public override bool Equals(object obj)
{
    var a = obj as A;
    return a != null &&
           Id == a.Id &&
           EqualityComparer<long?>.Default.Equals(Total, a.Total) &&
           ((Bs == null && model.Bs == null) || (Bs != null && model.Bs != null && Bs.SequenceEqual(model.Bs));
}

и это работает, но я не уверен в двух вещах:

  • Должен ли я что-то изменить в GetHashCode?
  • Могу ли я сделать это более читабельным и эффективным способом?

Спасибо!

...