IComparable和IComparer之间的区别

时间:2011-05-12 15:51:17

标签: c# .net icomparable icomparer

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

6 个答案:

答案 0 :(得分:84)

顾名思义,IComparable<T>读出我可比较。为IComparable<T>定义T时,您可以当前实例与另一个相同类型的实例进行比较IComparer<T>读出我是比较器,我比较IComparer<T>用于比较T的任意两个实例,通常超出T实例的范围。

至于它们的用途一开始可能会令人困惑。从定义中可以清楚地看出,因此IComparable<T>(在类T中定义)应该是提供排序逻辑的事实上的标准。 Sort等上的默认List<T>依赖于此。在IComparer<T>上实施T无助于定期排序。随后,除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> T同样class Person : IComparer<Person> 没有意义。

IComparable<T>

这是真的有效,但对眼睛看起来并不好看并且打败了逻辑。

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

IComparable<T>IEqualityComparer<T>完全类似于IEquatable<T>和{{1}},用于测试相等性而不是比较/排序;一个好的帖子here我在那里写了完全相同的答案:)

答案 1 :(得分:35)

  • IComparable - 使用CompareTo()方法定义对象的接口,该方法接受相同类型的另一个对象,并将当前对象与传递的对象进行比较。它将比较内部化到对象,允许更内联的比较操作,并且当只有一种逻辑方式或绝大多数常见的默认方式来比较类型的对象时,它非常有用。
  • IComparer - 使用Compare()方法定义一个接口,该方法接受另一种类型的两个对象(不必实现IComparable)并对它们进行比较。这使得比较外部化,并且当有许多可行的方法来比较类型的两个对象时,或者当类型没有实现IComparable时(或者IComparable实现比你想要的方式不同)并且你没有控制该类型的来源。

答案 2 :(得分:15)

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

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

答案 3 :(得分:6)

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

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

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

答案 4 :(得分:1)

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

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

另见:When to use IComparable<T> Vs. IComparer<T>

答案 5 :(得分:0)

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

作为实现IComparer的类实例的对象可用于比较对象对。 (将IComparer读作“我可以比较。”)此接口上的方法是Compare。如果要将比较逻辑与要比较的对象类分离,这非常有用。如果您有各种比较对象的方法(这种不区分大小写与区分大小写的字符串比较),您可以使用此方法。