Answers:
那么,他们是不是相当同样的事情IComparer<T>
在一个类型,能够在比较两个不同对象的实现IComparable<T>
是在那些能够将自己与其他同类型的实例比较类型来实现。
IComparable<T>
当我需要了解另一个实例与实例之间的关系时,我会经常使用它this
。 IComparer<T>
作为IComparer<T>
比较之外的标准,可用于对集合进行排序。
IComparable
为我可比。这意味着我可以与其他事物进行比较。和阅读IComparer
作为我是一个比较器,我简单地比较,这意味着我比一些事情。
它取决于实体。例如,对于诸如“ Student”之类的类,遵循基于Name的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”想要比较基于EnglishScore的学生。最好单独实现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;
}
}
这完全取决于您的类型是否可变。你只应该非可变类型实现IComparable。请注意,如果实现IComparable,则必须重写Equals以及==,!=,<和>运算符(请参阅代码分析警告CA1036)。
从此博客文章引用Dave G :
但是正确的答案是,如果您的对象是可变的,则实现IComparer而不是IComparable,并在必要时将IComparer的实例传递给排序函数。
由于IComparer只是该时间点用于排序的一次性对象,因此您的对象可以具有所需的任何可变语义。此外,它甚至不需要甚至不建议使用Equals,GetHashCode或==-您可以随意定义它。
最后,您可以为您的类型定义多个IComparer,以对不同的字段或不同的规则进行排序。这比坚持一个定义要灵活得多。
简而言之: 将IComparable用于值类型,将IComparer用于引用类型。
通过故事简单说明
高中篮球。对于团队来说,这是一个校园选择。我想招募团队中最高/最高/最快的人。我该怎么办?
IComparer界面 -比较两个人分开的人
Compare(Fred, John)
它吐出谁更好。IComparable呢?-与别人比较自己
您最近去过FB吗?您会看到其他人在做一些很棒的事情:环游世界,创造发明,而我做的事情却不那么酷-我们正在做的就是利用IComparable接口。
那比较器类呢?
Comparer类是实现IComparer接口的抽象基类。您应该从此类中派生出来,以进行具体的实现。无论如何,Microsoft建议您不要使用Comparer类,而不要实现IComparer接口:
我们建议您从Comparer类派生而不是实现IComparer接口,因为Comparer类提供了IComparer.Compare方法和Default属性的显式接口实现,该属性获取对象的默认比较器。
希望这些故事能帮助您记住。
正如其他人所说,他们做的事情不一样。
无论如何,这些天我倾向于不使用IComparer。我为什么要?它的职责(用于比较两个对象的外部实体)可以通过lambda表达式来处理,这与大多数LINQ方法的工作方式类似。编写一个快速的lambda,它将要比较的对象作为参数,并返回布尔值。而且,如果对象定义了自己的固有比较操作,则可以实现IComparable。
IComparer是用于对Array进行排序的接口,该接口将强制类实现Compare(T x,T y)方法,该方法将比较两个对象。实现此接口的类的实例用于Array的排序。
IComparable是在类型中实现的接口,该类型需要比较相同类型的两个对象,此可比接口将强制该类实现以下方法CompareTo(T obj)
IEqualityComparer是一个用于查找对象是否相等的接口,现在我们将在示例中看到该接口,我们必须在集合中查找对象的唯一性。该接口将实现方法Equals(T obj1,T obj2)
现在我们来看一个Example例子,我们有一个Employee类,基于这个类,我们必须创建一个Collection。现在我们有以下要求。
使用数组类2对数组进行排序。需要使用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
}
公共类EmployeeIdSorter:IComparer {public int Compare(Employee x,Employee y){if(x.Id <y.Id)return 1; 否则(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