可比较的和可比较的

本文关键字:可比较 | 更新日期: 2023-09-27 18:07:23

我应该同时实现IComparable和通用IComparable<T>吗?如果我只实现其中一个,会有什么限制吗?

可比较的和可比较的

是的,你应该两者都实现。

如果你实现了其中一个,任何依赖于另一个的代码都会失败。

有很多代码使用IComparableIComparable<T>,但不是两者都使用,因此实现两者确保您的代码将与这些代码一起工作。

Oded是正确的,你应该实现这两个,因为有集合和其他类只依赖于一个实现。

但是这里有一个技巧:不应该抛出异常,而IComparable应该抛出异常。在实现icparable 您负责确保T的所有实例都可以相互比较。这也包括null(将null视为小于T的所有非空实例,您将会很好)。

但是,general iccomparable接受System。对象,并且不能保证所有可能的对象都可以与t的实例进行比较。因此,如果将非t实例传递给IComparable,只需抛出System.ArgumentException。否则,将调用路由到iccomparable 实现。

示例如下:

public class Piano : IComparable<Piano>, IComparable
{
    public int CompareTo(Piano other) { ... }
    ...
    public int CompareTo(object obj)
    {
        if (obj != null && !(obj is Piano))
            throw new ArgumentException("Object must be of type Piano.");
        return CompareTo(obj as Piano);
    }
}

这个例子是一篇更长的文章的一部分,该文章包含了在实现IComparable时应该注意的副作用的广泛分析:基类和派生类中的接口

则会出现相反的情况。对象的语义。Equals和IEquatable暗示无论何时公平<定义时,它的行为应该反映Object的行为。等于(除了可能更快和避免拳击)。当两个类型为DerivedFoo的对象作为DerivedFoo类型比较为相等时,作为类型为Foo的对象比较也应该相等,反之亦然。另一方面,完全有可能两个DerivedFoo类型的对象在被视为DerivedFoo类型时排名不相等,但在被视为Foo类型时排名相等。确保这一点的唯一方法是使用iccomparable>.

假设,例如,一个类scheduleevent包含字段scheduletime (DateTime类型)和scheduleaction (MethodInvoker类型)。类包括子类型SchedulerEventWithMessage(它添加了一个string类型的Message字段)和SchedulerEventWithGong(它添加了一个Double类型的GongVolume字段)。SchedulerEvent类具有按scheduletime排序的自然顺序,但是相对于彼此无序的事件完全有可能不相等。SchedulerEventWithMessage和SchedulerEventWithGong类之间也有自然的顺序,但与SchedulerEvent类的项相比就不是这样了。

假设在同一时间安排了两个SchedulerEventWithMessage事件X和Y,但是X. message是"aardvark",Y. message是"zymurgy"。((IComparable)X). compareto (Y)应该报告零(因为事件有相等的时间)但是((IComparable)X). compareto (Y)应该返回一个负数(因为"aardvark"排序在"zymurgy"之前)。如果类不这样做,将很难或不可能一致地排序包含scheduleeventwithmessage和scheduleeventwithgong对象混合的列表。

顺便提一下,有人可能会说,拥有等价的语义是有用的。只比较类型T的成员的基础对象,以便例如:IEquatable<将检查scheduletime和scheduleaction是否相等,但即使应用于scheduleeventwithmessage或scheduleeventwithgong也不会检查Message或GongVolume属性。实际上,对于一个等价的>方法,我更喜欢这样的语义,但有一个问题:Comparer.Default.GetHashCode(T)总是调用相同的函数Object.GetHashCode(),而不管类型T是什么。这极大地限制了IEquatable