IComparable和IComparer之间的区别
本文关键字:区别 之间 IComparer IComparable | 更新日期: 2023-09-27 17:56:09
IComparable
接口和IComparer
接口有什么区别?是否有必要始终将此接口与Array.Sort()
一起使用
名思义,IComparable<T>
读出来我是可比的。 IComparable<T>
为 T
定义时,允许您将当前实例与相同类型的另一个实例进行比较。 IComparer<T>
读出我是一个比较者,我比较。 IComparer<T>
用于比较任何两个T
实例,通常在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.
同样,IComparer<T>
T
也没有意义。
class Person : IComparer<Person>
确实,这行得通,但看起来不太好看,并且违背了逻辑。
通常你需要的是 IComparable<T>
.此外,理想情况下,您可以只有一个IComparable<T>
而根据不同的标准可以进行多个IComparer<T>
。
IComparer<T>
和IComparable<T>
与用于测试相等性而不是比较/排序的IEqualityComparer<T>
和IEquatable<T>
完全相似;在这里我写了完全相同的答案是一个很好的线程:)
- IComparable - 使用 CompareTo() 方法为对象定义一个接口,该方法采用相同类型的另一个对象并将当前对象与传递的对象进行比较。它将与对象的比较内部化,允许进行更内联的比较操作,并且当只有一种逻辑方法或非常常见的默认方法来比较某种类型的对象时,它很有用。
- IComparer - 使用 Compare() 方法定义一个接口,该方法采用两个不同类型的对象(不必实现 IComparable)并比较它们。这会将比较外部化,并且当有许多可行的方法来比较一个类型的两个对象时,或者当类型未实现 IComparable(或 IComparable 实现的比较方式与您想要的方式不同)并且您无法控制该类型的源时,这很有用。
我读过的最好的解释是"要排序的对象将实现IComparable,而要对对象进行排序的类将实现IComparer。(来源)
如果您尝试排序的对象没有实现 IComparable,则需要创建一个实现 IComparer 的类(并接受这些对象类型进行比较)并将其传递给 Array.Sort() 方法。
> IComparable 用于为对象提供默认排序顺序。
IComparer是提供额外的比较机制。
请参阅本文以供参考。http://support.microsoft.com/kb/320727
>IComparer比较它给出的两个对象。IComparable由正在比较的对象实现,目的是与另一个对象进行比较。
最好实现 IComparable 来对对象进行排序。IComparable 可用于按不同条件进行排序(例如,按对象中的可选字段排序)。
另请参阅:何时使用 IComparable
实现IComparable
的类的实例的对象可以与其他对象进行比较。(IComparable
读作"我可以被比较"。此接口上执行此操作的方法是 CompareTo
.如果您希望此类类的实例知道如何将自己与其他对象进行比较,这将非常有用。
作为实现IComparer
的类的实例的对象可用于比较对象对。(IComparer
读为"我可以比较"。此接口上执行此操作的方法Compare
。如果要将比较逻辑与要比较的对象类分离,这将非常有用。如果您有多种比较对象的方法(这种不区分大小写与区分大小写的字符串比较),则可以使用它。