У меня есть следующие классы с переопределениями 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?
- Могу ли я сделать это более читабельным и эффективным способом?
Спасибо!