2010-07-16 69 views
1

對於具有屬性A,B,C,D,StartDate和EndDate的對象,如果我想實現任何兩個對象相同(如果它們具有相同的A,B和C並且重疊日期範圍,這將如何完成?Equals,GetHashCode,EqualityComparers和模糊相等

我試圖創建一個EqualityComparer像這樣

public override bool Equals(RateItem x, RateItem y) 
    { 
     bool equal = true; 
     if ((x.A != y.A || x.B != y.B || x.C != y.C || 
      (x.StartDate < y.StartDate && x.EndDate <= y.StartDate) || 
      (x.StartDate > y.StartDate && y.EndDate <= x.StartDate))) 
     { equal = false; } 
     return equal; 
    } 

但似乎很多框架中的地方忽略Equals和使用的GetHashCode和文檔並不清楚這一點的。當我去實現GetHashCode時,我不知道如何讓HashCodes在不忽略日期的情況下完成相同的操作。

爲了使它更具體些,這與項目管理和費率有關。我想實施一項業務規則,即同一角色的同一項目上的同一個人在同一時間段內不能享受不同的費率。因此,在DeathMarch項目中擔任DBA角色的Bob只能在任何給定時間有一個有效的帳單費率來記錄他的時間。如果他需要在相同的時間段內以不同的速率記錄一些小時的質量保證分析員的角色,那麼這是可以的。這是一個龐大的預先存在的系統,所以更改域對象結構不是一種選擇。

回答

2

這是不可能的。

.Net中的平等必須是過渡性的,這意味着如果a == bb == c,然後a == c

+0

您可以定義自己的'IsInConflictWith'樣的方法,並做了N^2檢驗。一個更好的解決方案是將它全部放在一個'DetectConflicts'方法中,該方法通過'StartDate'命令它們,然後檢查單遍的重疊。 – 2010-07-16 18:59:22

0

如果您使用的是一個哈希表,然後自己的GetHashCode方法將被用於最初測試相等,如果他們的哈希值的項目被發現相當於其Equals方法的調用將作出確定它們是否等於。

從文檔:

「但是,這是不夠的哈希表 ,以確定它們是相同的 對象可惜沒有如果 哈希表中找到與 相同的哈希兩個對象,?。它調用它們的Equals 方法來查看兩個對象 實際上是否相等。同樣,如果兩個對象是 兩個不同的實例,Object.Equals的默認實現將返回false同樣的 類。所以我們還需要爲我們的課程添加Equals 方法的覆蓋。

2

這是可能的。 GetHashCode的唯一規則是,如果A == B,則A.GetHashCode()必須等於B.GetHashCode()。相反,如果A == B A.GetHashCode()== B.GetHashCode()不必是真正。

所以,你可以簡單地做的GetHashCode像這樣

public override int GetHashCode() 
{ 
    return A.GetHashCode()^B.GetHashCode()^C.GetHashCode(); 
} 

GetHashCode的不是身份!它用於分組「相似」的對象。

證明:

string a = "a"; 
string b = "EUKCnPMLpp"; 
Console.WriteLine("a = '{0}', b = '{1}', Same = {2}", a, b, a == b); 
Console.WriteLine("a.GetHashCode() = {0}, b.GetHashCode() = {1}, Same = {2}", a.GetHashCode(), b.GetHashCode(), a.GetHashCode() == b.GetHashCode()); 
+0

你的第一句話有錯誤。 – SLaks 2010-07-18 02:45:01

+1

這不會幫助。有可能無限數量的不相等但重疊的對象。 – SLaks 2010-07-18 02:45:34

+0

我沒有犯錯。您的錯誤是將身份與GetHashCode的目的混淆。如果你要反駁這個陳述,請提供一個具體的例子。 – Tergiver 2010-07-18 12:41:27

相關問題