Я пытаюсь написать компаратор равенства для простого класса с 3 полями, например:
public class NumberClass
{
public int A { get; set; }
public int B { get; set; }
public int C { get; set; }
}
Мое условие равенства двух объектов NumberClass
состоит в том, что Obj1.A == Obj2.A || Obj1.B == Obj2.B
(другими словами, ИЛИ), Obj1 и Obj2 являются экземплярами NumberClass
.
Я могу легко записать Equals()
моего компаратора следующим образом, но я не знаю, что делать с моим методом GetHashCode()
.
public bool Equals(NumberClass x, NumberClass y)
{
if (x.A == y.A || x.B == y.B)
return true;
else
return false;
}
public int GetHashCode(NumberClass obj)
{
return ???
}
Если бы моим условием равенства было И вместо ИЛИ, я мог бы написать свой GetHashCode()
следующим образом, взятый из этого ответа SO.
public int GetHashCode(NumberClass obj)
{
unchecked
{
int hash = 17;
if (obj != null)
{
hash = hash * 23 + obj.A.GetHashCode();
hash = hash * 23 + obj.B.GetHashCode();
}
return hash;
}
}
Но это, очевидно, не будет работать для ИЛИ, поскольку только одно из A
или B
достаточно, чтобы мое условие равенства было истинным.
Один обходной путь, о котором я мог подумать, всегда возвращает одно и то же значение в GetHashCode()
, которого было бы достаточно для операций LINQ, таких как Distinct()
, но я чувствую, что должен быть другой способ, поскольку у него есть свои недостатки.
Как правильно поступить в этой ситуации?
P.S. Для тестирования представьте, что мой Main() выглядит следующим образом:
static void Main(string[] args)
{
List<NumberClass> list = new List<NumberClass>();
list.Add(new NumberClass { A = 1, B = 2, C = 3 });
list.Add(new NumberClass { A = 1, B = 22, C = 33 });
var distinct = list.Distinct(new NumberComparer());
Console.ReadKey();
}
Я ожидаю, что distinct
будет содержать только первый элемент в списке.