簡體   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