6

这可能是一个微不足道的问题,但我没有找到任何关于此的信息:实现类型 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;
}

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

4

3 回答 3

6

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

如果在特定情况下它比您想要做的任何其他实现更简单,那没关系 - 但我不能说我曾经遇到过这种情况。像这样的比较几乎总是用于对同质集合或类似的东西进行排序。

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

于 2010-03-29T16:25:00.507 回答
2

实现这样的事情是很美好的。但这不是一个好习惯。

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

Foo x = new Foo();

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

你会说“天哪!如何将 15 与 x 进行比较?”?这将使代码的可读性降低..

最好将比较添加为这样的函数: public int IsMoreThanPrivateI(int x);

于 2010-03-29T16:25:56.150 回答
1

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

作为这种类型的东西可能有用的一个例子,想象一个存储字符串的类族;一个字符串可能存储为一个简单的 String 对象,但一些字符串可能存储为一个字符和重复计数,其他可能存储为对更长字符串的引用以及起始偏移量和长度等。通过将两个字符串对象转换为类型“String”然后进行比较来比较两个字符串对象,但是在许多情况下存在更好的比较方法。例如,如果一个字符串存储为“Character 'Z' repeat 100,000 times”,而另一个字符串存储为“Literal string 'Dog'”,则前一个字符串可以通过观察后者的第一个字符是小于“Z”。

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

于 2011-06-26T15:41:21.530 回答