我試圖寫一個相等比較的簡單類3場,就像這樣:當等式比較器基於OR操作時,編寫GetHashCode()的正確方法是什麼?
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 ???
}
如果我的平等條件是和代替或者,我可以寫我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;
}
}
但這顯然不會支持或因爲只有A
或B
相等的一個工作就足夠了我平等的條件是真實的。
一個解決辦法,我能想到的總是返回在GetHashCode()
相同的值就足以LINQ操作,如Distinct()
,但我覺得應該有另一種方式爲有自身的缺點。
什麼是處理這種情況的正確方法?
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
僅包含在列表中的第一個元素。
能否請您解釋一下你的_it意思假定平等將是transitive_? – Sach
@Sach如果A等於B,B等於C,那麼A等於C(如果等於傳遞)。你的情況並非如此。 – Servy
明白了,謝謝! 好吧,我想在這種情況下唯一的解決方法是在'GetHashCode()'中返回相同的值,或者根本不使用比較器並進行舊學校比較。 – Sach