何时使用IComparable <T> Vs. 的IComparer <T>

我试图找出我需要实现哪些接口。 他们都基本上做同样的事情。 我什么时候可以使用一个呢?

那么它们与IComparer<T>在一个能够比较两个不同对象的types上实现的并不完全相同 ,而IComparable<T>则是在能够与其他相同types的实例进行比较的types上实现的。

当我需要知道另一个实例与this实例有什么关系时,我倾向于使用IComparable<T>IComparer<T>对sorting集合非常有用,因为IComparer<T>不在比较之列。

当类有内在的比较时,使用IComparable<T>

如果需要比较IComparer<T>内部比较的比较方法(如果有比较方法),则使用IComparer<T>

这取决于实体。 例如,像“学生”这样的课程,基于名称的IComparable将是有意义的。

 class Student : IComparable { public string Name { get; set; } public int MathScore { get; set; } public int EnglishScore { get; set; } public int TotalScore { get { return this.MathScore + this.EnglishScore; } } public int CompareTo(object obj) { return CompareTo(obj as Student); } public int CompareTo(Student other) { if (other == null) { return 1; } return this.Name.CompareTo(other.Name); } } 

但是,如果“A”老师想根据MathScore比较学生,而“B”老师想根据英语分数比较学生。 分开实现IComparer将是个好主意。 (更像是一种战略模式)

 class CompareByMathScore : IComparer<Student> { public int Compare(Student x, Student y) { if (x.MathScore > y.MathScore) return 1; if (x.MathScore < y.MathScore) return -1; else return 0; } } 

这一切都取决于你的types是否可变。 您应该在非可变types上实现IComparable。 请注意,如果实现IComparable,则必须覆盖Equals以及==,!=,<和>运算符(请参阅代码分析警告CA1036)。

引用Dave G的博客文章 :

但正确的答案是实现IComparer而不是IComparable,如果您的对象是可变的,并在必要时传递IComparer的实例sorting函数。

由于IComparer只是一个用于在那个时间点进行sorting的一次性对象,因此您的对象可以具有任何您想要的可变语义。 此外,它不需要甚至build议使用Equals,GetHashCode或== – 您可以自由地以任何方式定义它。

最后,您可以为您的types定义多个IComparer,以便在不同的字段或不同的规则上进行sorting。 这比坚持一个定义要灵活得多。

简而言之: 对值types使用IComparable,对引用types使用IComparer。

通过故事的简单解释

高中篮球。 这是一个校队select的球队。 我想要得到团队中最高/最好/最快的人。 我该怎么办?

Icomparer接口 – 比较两个人分开的人

  • 这让我可以比较任何两个人排队………这基本上是。 弗雷德和约翰……….我把他们扔进一个实现界面的具体类。 Compare(Fred, John) ,它吐出谁更好。

那么IComparable呢? – 比较自己与别人

你最近去过FB吗? 你会看到其他人做很酷的事情:在世界各地旅行,创造发明,而你被困在妈妈地下室写栈溢出的答案 – 以及你在做什么是利用IComparable接口。

  • 你正在比较当前的实例(你自己)与另一个对象(别人)是同一types(人)。

那么比较类呢?

Comparer类是实现Icomparer接口的抽象基类。 你应该从这个类派生出具体的实现。 无论如何,Microsoftbuild议您使用Comparer类而不是实现Icomparer接口:

我们build议您从Comparer类派生而不是实现IComparer接口,因为Comparer类提供了IComparer.Compare方法的显式接口实现和获取对象的默认比较器的Default属性。

概要

  • IComparer – 排队两件事情,并比较。
  • IComparable – 与FB上的其他人进行比较。

希望故事能帮助你记住。

正如其他人所说,他们不这样做。

无论如何,这些天我都不会使用IComparer。 我为什么要? 它的责任(用于比较两个对象的外部实体)可以用lambdaexpression式处理得更干净,类似于大多数LINQ方法的工作方式。 写一个快速的lambda,它将对象作为参数进行比较,并返回一个布尔值。 如果对象定义了自己的内部比较操作,则可以实现IComparable。

IComparable说一个对象可以与另一个对比。 IComparer是一个可以比较任何两个项目的对象。

IComparer是一个用来sorting数组的接口,这个接口将强制这个类实现Compare(T x,T y)方法,它将比较这两个对象。 实现此接口的类的实例用于Array的sorting。

IComparable是一个接口实现的types,它需要比较同一types的两个对象,这个可比较的接口将迫使类实现下面的方法CompareTo(T obj)

IEqualityComparer是一个用于查找对象是否为Equal的接口,现在我们将在一个示例中看到这一点,在这个示例中,我们必须在集合中find对象的Distinct。 这个接口将实现一个方法Equals(T obj1,T obj2)

现在我们举一个例子,我们有一个Employee类,基于这个类我们必须创build一个Collection。 现在我们有以下要求。

使用Array类对数组进行sorting2.需要使用Linq的集合:删除重复,按高低顺序删除,删除一个员工ID

 abstract public class Person { public string FirstName { get; set; } public string LastName { get; set; } public string Address { set; get; } } public enum SortType { ByID, BySalary } 

public class EmployeeIdSorter:IComparer {public int Compare(Employee x,Employee y){if(x.Id <y.Id)return 1; else if(x.Id> y.Id)返回-1; 否则返回0; }}

  public class EmployeeSalarySorter : IComparer<Employee> { public int Compare(Employee x, Employee y) { if (x.Salary < y.Salary) return 1; else if (x.Salary > y.Salary) return -1; else return 0; } } 

欲了解更多信息参考下面http://dotnetvisio.blogspot.in/2015/12/usage-of-icomparer-icomparable-and.html