62

IComparableIComparer接口有什么区别?是否有必要始终使用此接口与Array.Sort()方法

4

6 回答 6

105

顾名思义,IComparable<T>读出来我是可比的。IComparable<T>当定义为T允许您当前实例与另一个相同类型的实例进行比较。IComparer<T>读出我是一个比较者,我比较IComparer<T>用于比较 的任何两个实例T,通常在 的实例范围之外T

至于它们的用途,起初可能会令人困惑。从定义中应该很清楚,因此IComparable<T>(在类T本身中定义)应该是提供排序逻辑的事实上的标准。etc 上的默认值Sort依赖于此。List<T>实施IComparer<T>onT无助于定期排序。随后,在IComparable<T>T. 这个:

class MyClass : IComparable<T>

很少有意义。

另一方面

class T : IComparable<T>
{
    public int CompareTo(T other)
    {
        //....
    }
}

应该怎么做。

IComparer<T>当您需要根据自定义顺序进行排序时可能很有用,但不是一般规则。例如,在某个类别中Person,您可能需要根据年龄对人员进行排序。在这种情况下,您可以这样做:

class Person
{
    public int Age;
}

class AgeComparer : IComparer<Person>
{
    public int Compare(Person x, Person y)
    {
        return x.Age - y.Age;
    }
}

现在AgeComparer有助于根据Age.

var people = new Person[] { new Person { age = 23 }, new Person(){ age = 22 } };
people.Sort(p, new AgeComparer()); //person with age 22 comes first now.

同样IComparer<T>onT没有意义。

class Person : IComparer<Person>

确实,这可行,但看起来不太好,并且不符合逻辑。

通常你需要的是IComparable<T>. 理想情况下,您只能拥有一个IComparable<T>,而IComparer<T>根据不同的标准可以有多个。

IComparer<T>and 与 and完全IComparable<T>类似,IEqualityComparer<T>用于IEquatable<T>测试相等性而不是比较/排序;一个很好的线程在这里我写了完全相同的答案:)

于 2012-12-06T18:38:54.633 回答
42
  • IComparable - 使用 CompareTo() 方法为对象定义一个接口,该方法采用另一个相同类型的对象并将当前对象与传递的对象进行比较。它将比较内化到对象,允许更内联的比较操作,并且在只有一种逻辑方式或绝大多数常见的默认方式来比较类型的对象时很有用。
  • IComparer - 使用 Compare() 方法定义一个接口,该方法采用另一种类型的两个对象(不必实现 IComparable)并比较它们。这将比较外部化,当有许多可行的方法来比较一个类型的两个对象时,或者当该类型没有实现 IComparable(或者 IComparable 实现的比较方式与您想要的不同)并且您没有时,这很有用可以控制该类型的来源。
于 2011-05-12T15:56:24.583 回答
16

我读过的最好的解释是“要排序的对象将实现 IComparable,而要对对象进行排序的类将实现 IComparer。” (来源

如果您尝试排序的对象未实现 IComparable,则需要创建一个实现 IComparer 的类(并接受这些对象类型进行比较)并将其传递给 Array.Sort() 方法。

于 2011-05-12T15:55:55.030 回答
7

IComparable 用于为您的对象提供默认排序顺序。

IComparer 是提供额外的比较机制。

请参阅这篇文章以供参考。 http://support.microsoft.com/kb/320727

于 2011-10-20T07:19:01.597 回答
1

IComparer 比较它给出的两个对象。IComparable 由正在比较的对象实现,目的是与自身的另一个对象进行比较。

实现 IComparable 以对对象进行排序是一个好主意。IComparable 可用于按不同标准排序(例如,按对象中的可选字段排序)。

另请参阅:何时使用 IComparable<T> Vs。比较器<T>

于 2011-05-12T15:57:07.167 回答
1

作为实现类的实例的对象IComparable可以与其他对象进行比较。(读IComparable作“我可以被比较”。)这个接口上的方法是CompareTo. 如果您希望此类类的实例知道如何将自己与其他对象进行比较,这将很有用。

作为实现类的实例的对象IComparer可用于比较对象对。(读IComparer作“我可以比较”。)此接口上执行此操作的方法是Compare. 如果您想将比较逻辑与被比较的对象类分离,这很有用。如果您有各种比较对象的方法(此不区分大小写与区分大小写的字符串比较),您可能会使用它的一种情况。

于 2011-05-12T17:37:56.183 回答