IComparable
和IComparer
接口之间有什么区别?是否有必要始终使用此Array.Sort()
方法
答案 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)
答案 2 :(得分:15)
我读过的最好的解释是“要排序的对象将实现IComparable,而要对对象进行排序的类将实现IComparer。” (source)
如果您尝试排序的对象没有实现IComparable,则需要创建一个实现IComparer的类(并接受这些对象类型进行比较)并将其传递给Array.Sort()方法。 / p>
答案 3 :(得分:6)
答案 4 :(得分:1)
IComparer会比较它给出的两个对象。 IComparable由被比较的对象实现,目的是与另一个对象进行比较。
实现IComparable以排序对象是个好主意。 IComparable可用于按不同标准排序(例如,按对象中的可选字段排序)。
答案 5 :(得分:0)
可以将实现IComparable
的类实例的对象与其他对象进行比较。 (将IComparable
读作“我可以进行比较。”)此接口上执行此操作的方法是CompareTo
。如果您希望此类的实例知道如何将自己与其他对象进行比较,这将非常有用。
作为实现IComparer
的类实例的对象可用于比较对象对。 (将IComparer
读作“我可以比较。”)此接口上的方法是Compare
。如果要将比较逻辑与要比较的对象类分离,这非常有用。如果您有各种比较对象的方法(这种不区分大小写与区分大小写的字符串比较),您可以使用此方法。