[英]Why when i call the remove operation of this hashset it doesn't use the gethashcode neither the equality implementation?
[英]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無效,因為只有A
或B
相等才足以使我的相等條件成立。
我能想到的一種解決方法是,總是在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.