2

我正在尝试为具有 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(换句话说,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()如下,取自这个 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 操作(如

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

PS为了测试,假设我的 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只包含列表中的第一个元素。

4

1 回答 1

4

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

只要您有这样的“模糊”相等性,您就根本无法使用任何基于哈希的算法。

于 2017-08-09T21:47:12.577 回答