C# 如何实现这个特定的类层次结构?

C# 如何实现这个特定的类层次结构?,c#,oop,C#,Oop,我有一系列类正在实现comparable接口中的CompareTo方法 public int CompareTo(CMNewsletter obj) { CMNewsletter c = obj; return String.Compare(c.Name, this.Name); } 每个类都有自己的比较实现。所以实现应该在每个类中完成 现在需要在一些基类对象上调用CompareToCMBase是前面提到的所有类的基类 下面的代码是我想要

我有一系列类正在实现
comparable
接口中的
CompareTo
方法

    public int CompareTo(CMNewsletter obj)
    {
        CMNewsletter c = obj;
        return String.Compare(c.Name, this.Name);
    }
每个类都有自己的
比较
实现。所以实现应该在每个类中完成

现在需要在一些基类对象上调用CompareTo
CMBase
是前面提到的所有类的基类

下面的代码是我想要如何设计我的类

CMBase reference, copy;
if (reference.CompareTo(copy) == 0)
{
    Console.WriteLine("Not changed");
}
reference
copy
对象将是
CMNewsletter
类型或其他类型,而
CompareTo
的实际实现就在这些对象中


我不确定如何实现整个类层次结构来完成我所描述的。

我将使CMBase抽象类实现IComparable接口作为抽象方法:

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

这将使所有派生类实现CompareTo方法。如果您不能使这个类抽象,那么您可以使实现虚拟化,这只会引发异常,或者如果可以接受,则实现一些默认的比较逻辑。

首先,您需要实现
IEquatable
而不是
IComparable
。然后介绍两种助手方法,即
EqualsHelper
EqualsCore
,以完成任务

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;
    }
}
类MyBase:IEquatable
{
公共布尔等于(MyBase其他)
{
返回EqualHelper(其他);
}
公共覆盖布尔等于(对象对象对象)
{
返回equalHelper(对象作为MyBase);
}
受保护的布尔EqualsHelper(MyBase其他)
{
if(ReferenceEquals(null,other))返回false;
if(ReferenceEquals(this,other))返回true;
if(other.GetType()!=this.GetType())返回false;
返回相等核心(其他);
}
受保护的虚拟bool EqualsCore(MyBase其他)
{
return BaseProperty==other.BaseProperty;
}
公共覆盖int GetHashCode()
{
归还基本财产;
}
公共int BaseProperty{get;set;}
}
派生类:MyBase,IEquatable
{
公共int-DerivedProperty{get;set;}
公共布尔等于(派生其他)
{
返回EqualHelper(其他);
}
受保护的覆盖布尔EqualsCore(MyBase其他)
{
派生对象=(派生)其他;
返回基。相等核心(obj)&&
this.DerivedProperty==obj.DerivedProperty;
}
}

是否确实要将一些
CMNewsletter
与另一个派生对象进行比较?比较基本字段还不够吗(当然应该是!)-如果你想让类保持打开状态,你就不能以合理的方式这样做如果你总是调用CompareTo并像这样检查0
CompareTo()==0
,你可能实现了错误的接口,然后您需要实现
IEquatable
。鉴于WriteLine输出“未更改”,您似乎在尝试查看对象是否相同,而这不是
IComparable
的目的
IEquatable
会告诉您5不等于7
IComparable
会告诉您5在7之前。@Carsten König:是的,我想将
CMNewsletter
与另一个
CMNewsletter
实例进行比较,使用一些基类对象作为
reference
copy
。但是这也可以是另一个类,比如
CMEvent
,我不希望处理
reference
/
copy
比较的代码知道每个子类。我想我想要的是多态性?@Sriram Sakthivel,@Andrew Counts:我将把
IComperable
替换为
IEquatable
,但问题仍然是一样的。
CMBase是抽象的,但它包含在非抽象类中
@Pablo那又怎样?那么它不能实现IComparable吗?@Pablo,首先,你没有在问题中指定,你的类包含在另一个类中,所以我不明白你为什么认为我应该知道这一点。第二,若抽象类包含在非抽象类中,这并不妨碍它实现像IComparable这样的接口。我双击了它,它编译成功了。或者还有什么你没有指定的,我应该猜到的?是的,这是我也尝试过的方式,但我觉得很奇怪-当调用child
Equals
时,它调用的是家长的助手,而助手调用的是child的
EqualsCore
。没有办法避免这种跳跃?虽然这看起来像是在解决这个问题,但换句话说,这是最好的方法吗?@Pablo这就是我们所说的多态性或后期绑定,无论如何,您需要在所有类型中覆盖
Equals(object obj)
,所以对我来说,这是一种很好的方法。如果没有其他更好的答案,请尝试一下:)