我正在尝试为一个具有 3 个字段的简单类编写一个相等比较器,如下所示:
public class NumberClass
{
public int A { get; set; }
public int B { get; set; }
public int C { get; set; }
}
我的两个 NumberClass
对象相等的条件是 if Obj1.A == Obj2.A || Obj1.B == Obj2.B
(换句话说,OR),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 ???
}
如果我的相等条件是 AND 而不是 OR,我可以按如下方式编写 GetHashCode()
:taken from this SO answer .
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;
}
}
但这显然不适用于 OR,因为只有 A
或 B
之一相等就足以使我的相等条件成立。
我能想到的一种解决方法是始终在 GetHashCode()
中返回相同的值,这对于 Distinct()
等 LINQ 操作来说足够了,但我觉得应该有另一种方法,因为它有其自身的缺点。
处理这种情况的正确方法是什么?
附注 为了进行测试,假设我的 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
仅包含列表中的第一个元素。
最佳答案
对于您的情况没有解决方案。您的对象违反了相等比较器工作所必需的假设,例如,它假设相等将是传递的,但对于您的相等实现而言,情况并非如此。
只要你有这样的“模糊”等式,你就无法使用任何基于哈希的算法。
关于c# - 当相等比较器基于 OR 运算时,编写 GetHashCode() 的正确方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45601078/