2014-06-14 29 views
0

我的類實現IEquatable和IComparable。然後它被添加到一個排序集。Sortedset不使用自定義等於

目標是讓它按照它的「Date」屬性排序,如果「ID1」和「ID2」都相同,那麼它就是相等的。

的實現的方法:

public int CompareTo(MyClass other) 
{ 
    return other.Date.CompareTo(Date); 
} 

public override int GetHashCode() 
{ 
    unchecked 
    { 
     var hashCode = ID1; 
     hashCode = (hashCode * 397)^ID2; 
     return hashCode; 
    } 
} 

public bool Equals(MyClass other) 
{ 
    if (ReferenceEquals(null, other)) 
     return false; 

    if (ReferenceEquals(this, other)) 
     return true; 

    return ID1 == other.ID1 
     && ID2 == other.ID2; 
} 

將所得的SortedSet正確排序,但仍然有應該在組相等,因此不元素。使用斷點看起來既不GetHashCode也不等於被調用。

有關如何解決這個問題的任何提示?

回答

0

SortedSet使用CompareTo進行排序和平等比較。

沒有內置的有序集合,這將允許您指定一個不同的方法來比較排序中的相等性,而不是比較維護獨立性時的相等性。我不完全確定這是爲什麼,但它可能與用於排序的算法背後的假設有關。

如果你想這樣的行爲,可能做最簡單的方法是在包裝自己的類底層集合,這將增加新的項目到集合之前檢查明顯。

您還需要小心,這是平等的排序,但不等於你Equals方法的項目都可以添加到底層集合。在你的情況,其中,排序是由Date完成,平等是由ID1完成,ID2這可能看起來像:

public int CompareTo(MyClass other) 
{ 
    var result = other.Date.CompareTo(Date); 
    if(result != 0) 
     return result; 
    result = other.ID1.CompareTo(ID1); 
    if(result != 0) 
     return result; 
    return other.ID2.CompareTo(ID2); 
} 

這施加額外的排序,如果日期是相同的,但我不希望這是一個問題。

或者,您可以「欺騙」,通過強迫在排序位置上等於比較的項目。這可能是最好的移動到一個自定義IComparer,因爲它不是你想要的正常排序行爲,一SortedSet外:

public int CompareTo(MyClass other) 
{ 
    if(other.Equals(this)) 
     return 0; 

    var result = other.Date.CompareTo(Date); 
    if(result != 0) 
     return result; 
    result = other.ID1.CompareTo(ID1); 
    if(result != 0) 
     return result; 
    return other.ID2.CompareTo(ID2); 
} 

這將讓你避免創建一個圍繞收集自己的包裝類,和更安全。儘管如此,這是相當黑的。

相關問題