当 Equality Comparer 基于 OR 操作时,正确编写 GetHashCode() 的方法?

Proper way to write GetHashCode() when Equality Comparer is based on OR operation?

我正在尝试为具有 3 个字段的简单 class 编写相等比较器,如下所示:

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(换句话说,OR),Obj1 和 Obj2 是 NumberClass.[=26= 的实例]

我可以很容易地写出我的比较器的 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,因为只有 AB 中的一个相等足以使我的相等条件为真。

我能想到的一个解决方法是始终在 GetHashCode() 中返回相同的值,这对于 Distinct() 等 LINQ 操作来说已经足够了,但我觉得应该有另一种方法自身的缺点。

处​​理这种情况的正确方法是什么?

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 只包含列表中的第一个元素。

没有适合您的情况的解决方案。您的对象违反了平等比较器工作所必需的假设,例如,它假设平等将是可传递的,但您的平等实施并非如此。

只要您具有这样的 "fuzzy" 等式,您就无法使用任何基于散列的算法。