2014-07-22 58 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