IComparable
和IComparer
接口之间有什么区别?在使用Array.Sort()
方法时是否总是需要使用这个接口?
IComparable
和IComparer
接口之间有什么区别?在使用Array.Sort()
方法时是否总是需要使用这个接口?
IComparable<T>
读作 我可以比较。当为T
定义IComparable<T>
时,您可以将当前实例与另一个相同类型的实例进行比较。IComparer<T>
读作我是比较器,我比较。通常在T
实例之外比较任何两个T
实例时使用IComparer<T>
。IComparable<T>
(在类T
本身中定义)应成为提供排序逻辑的事实标准。默认的List<T>
等上的Sort
依赖于此。在T
上实现IComparer<T>
对于常规排序没有帮助。因此,在除T
以外的任何其他类上实现IComparable<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.
同样在 T
上使用 IComparer<T>
是没有意义的。
class Person : IComparer<Person>
确实,这样做是可行的,但不美观且违背逻辑。
通常您需要的是 IComparable<T>
。理想情况下,您只能拥有一个 IComparable<T>
,而可以根据不同的标准拥有多个 IComparer<T>
。
IComparer<T>
和 IComparable<T>
与用于测试相等性而非比较/排序的 IEqualityComparer<T>
和 IEquatable<T>
完全类似;在这里有一个很好的线程 here,我写了完全相同的答案 :)
IComparable<T>
是为了为 T
的实例提供默认顺序。不仅从名称 IComparable
中可以看出这一点,而且从 IComparable
上的 CompareTo
方法的定义中也可以看出这一点。该定义是 public int CompareTo(T)
,因此您可以执行 jon.CompareTo(mark)
,其中 jon 和 mark 当然是人名。当您编写 class RandomClass : IComparable<SomethingElse>
时,您的 CompareTo
会使代码看起来像 refrigerator.CompareTo(parrot)
。虽然在技术上某些情况下可能需要这样做,但 .NET 世界并不是这样做的。 - nawfalpublic int Compare(Refrigerator r, Parrot p)
。 - nawfal我看到的最好的解释是:“要进行排序的对象将实现IComparable接口,而将对这些对象进行排序的类将实现IComparer接口。” (来源)
如果您尝试排序的对象没有实现IComparable接口,则需要创建一个实现IComparer接口的类(并接受这些对象类型作为比较对象),然后将其传递给Array.Sort()方法。
IComparer比较给定的两个对象。IComparable是由正在比较的对象实现的,目的是与其自身的另一个对象进行比较。
实现IComparable对于排序对象是一个好主意。 IComparable可用于按不同标准排序(例如,按对象中可选择的字段排序)。
实现IComparable
接口的类的实例可以与其他对象进行比较。(将IComparable
读作“我可以比较”)。执行此操作的接口方法是CompareTo
。如果您希望这些类的实例知道如何将自己与其他对象进行比较,则此功能非常有用。
实现IComparer
接口的类的实例可用于比较对象对。(将IComparer
读作“我可以比较”)。执行此操作的接口方法是Compare
。如果您想要将比较逻辑与被比较对象的类分离,那么这个功能非常有用。一个使用场景是当您有多种比较对象的方式时(例如不区分大小写与区分大小写的字符串比较)。