繁体   English   中英

当Equal比较器基于OR操作时,正确编写GetHashCode()的方法吗?

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

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

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.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,则可以从SO答案中获取我的GetHashCode() ,如下所示。

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()返回相同的值,这对于LINQ操作(如Distinct() GetHashCode()就足够了,但是我觉得应该有另一种方法,因为它有自己的缺点。

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

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM