实现IComparable <notself> </notself>

时间:2010-03-29 16:18:27

标签: c# icomparable

这可能是一个微不足道的问题,但我没有找到任何关于此的信息:使用类型T实现IComparable<S>(T和S是两种不同的类型)是“有害的”还是被认为是不好的做法?

示例:

class Foo : IComparable<int>
{
    public int CompareTo(int other)
    {
        if (other < i) return -1;
        if (other > i) return 1;

        return 0;
    }

    private int i;
}

是否应该避免这种代码,如果是,为什么?

3 个答案:

答案 0 :(得分:6)

我至少会认为它“奇怪” - 特别是在那一点上,比较不会是对称的,这通常是正常比较合约的一部分。

如果某个特定的情况比任何其他实现你想要做的更简单,那就没关系 - 但我不能说我遇到过这样的情况。像这样的比较几乎总是用于排序同类集合或类似的东西。

您是否有特定的情况,或者只是一个“感兴趣”的问题?

答案 1 :(得分:2)

很有必要实施这样的事情。但这不是一个好习惯。

想象一下,你会看到一些像这样的代码:

Foo x = new Foo();

if( x.compareTo(15) > 0)
{
  //blah blah
}

你会说“噢,我的上帝!如何比较15到x?”? 这会降低代码的可读性..

最好将compare添加为如下函数: public int IsMoreThanPrivateI(int x);

答案 2 :(得分:1)

我可以看到用于比较不同类的对象,但我不认为IComparable(T)是正确的基础。对于真正起作用的这种比较,对象必须具有共同的规范形式,这意味着它们都来自共同的祖先或实现共同的接口。我进一步建议这个公共基础包括一个SecondChanceCompareTo方法,并且普通比较方法应该,如果它不能识别与它进行比较的精确类型,则将自身传递给传入对象的SecondChanceCompare方法

作为这类事物可能有用的例子,想象一下存储字符串的类系列;一个字符串可能存储为一个简单的String对象,但是某些字符串可能存储为字符和重复计数,其他字符串可能存储为对较长字符串的引用以及起始偏移量和长度等。有可能通过将两个字符串对象转换为类型“字符串”然后进行比较来比较两个字符串对象,但是在许多场景中存在更好的比较方法。例如,如果一个字符串存储为“字符'Z'重复100,000次”而另一个字符串存储为“文字字符串'狗'”,则前一个字符串可以通过观察后者的第一个字符是小于'Z'。

请注意,基本的“文字字符串”对象可能不知道如何将自身与“重复字符”字符串对象进行比较,除非将后者转换为文字字符串(昂贵的操作),但它可以调用后者的“SecondChanceCompare” “方法,它将知道如何将自己与文字字符串进行比较。