2014-07-22 55 views
0

我有一系列從IComparable接口實施CompareTo方法的類。如何實現這個特定的類層次結構?

public int CompareTo(CMNewsletter obj) 
    { 
     CMNewsletter c = obj; 
     return String.Compare(c.Name, this.Name); 
    } 

每個類都有自己的CompareTo實現。所以這個實現應該在每個類中完成。

現在需要在某些基類對象上調用CompareTo。 CMBase是前面提到的所有類的基類。

以下代碼是我想要設計我的類的方式。

CMBase reference, copy; 
if (reference.CompareTo(copy) == 0) 
{ 
    Console.WriteLine("Not changed"); 
} 

referencecopy目的將CMNewsletter型或其他,其中的CompareTo實際執行駐留的。

我不知道如何實現整個類層次結構來完成我所描述的。

+0

你真的想一些'CMNewsletter'比較另一個派生的對象?是不是足夠比較基礎字段(好吧*應該*!) - 如果你想保持類打開你不能以合理的方式做到這一點 – Carsten

+1

如果你總是調用CompareTo並像這樣檢查零, CompareTo()== 0',你可能實現了錯誤的接口,那麼你需要實現'IEquatable'。 –

+0

由於您的WriteLine輸出是「未更改」,因此您似乎在試圖查看對象是否相同,這與IComparable無關。 'IEquatable'會告訴你,5不等於7.'IComparable'會告訴你5之前7. – Claies

回答

1

首先您需要執行IEquatable而不是IComparable。然後你介紹兩個幫手方法,即EqualsHelperEqualsCore完成工作。

EqualsHelper只是一個幫助方法,用於查找相等是否失敗,並且EqualsCore是虛擬的,您需要在所有派生類中重寫並在其中實現其相等性,沒有別的。

class MyBase : IEquatable<MyBase> 
{ 
    public bool Equals(MyBase other) 
    { 
     return EqualsHelper(other); 
    } 

    public override bool Equals(object obj) 
    { 
     return EqualsHelper(obj as MyBase); 
    } 

    protected bool EqualsHelper(MyBase other) 
    { 
     if (ReferenceEquals(null, other)) return false; 
     if (ReferenceEquals(this, other)) return true; 
     if (other.GetType() != this.GetType()) return false; 
     return EqualsCore(other); 
    } 

    protected virtual bool EqualsCore(MyBase other) 
    { 
     return BaseProperty == other.BaseProperty; 
    } 

    public override int GetHashCode() 
    { 
     return BaseProperty; 
    } 

    public int BaseProperty { get; set; } 
} 

class Derived : MyBase, IEquatable<Derived> 
{ 
    public int DerivedProperty { get; set; } 

    public bool Equals(Derived other) 
    { 
     return EqualsHelper(other); 
    } 

    protected override bool EqualsCore(MyBase other) 
    { 
     Derived obj = (Derived)other; 
     return base.EqualsCore(obj) && 
      this.DerivedProperty == obj.DerivedProperty; 
    } 
} 
+0

是的,這也是我試圖去的方式,但在我看來很奇怪 - 當調用子類「Equals」時,它調用父級的助手,並且該助手正在調用子級的「EqualsCore」。沒辦法避免這種跳躍?雖然這看起來像解決這個問題,換句話說,這是最好的方法? – Pablo

+0

@Pablo這就是我們所說的多態或後期綁定,無論如何,你需要在所有類型中重寫'Equals(object obj)',所以對我來說這看起來不錯。試試看,如果沒有其他更好的答案:) –

-1

我會讓CMBase抽象類實現IComparable接口的抽象方法:

public abstract class CMBase : IComparable 
{ 
    public abstract int CompareTo(object o); 
} 

這將使所有派生類實現CompareTo方法。如果你不能使這個類抽象化,那麼你可以讓虛擬實現只是拋出異常,或者如果可以接受的話 - 實現一些默認的比較邏輯。

+0

'CMBase是抽象的,但它包含在非抽象類中# – Pablo

+1

@Pablo所以呢?它不能實現IComparable呢? –

+0

所以這是合理的編譯器錯誤。 – Pablo