Mic*_*cah 99 .net icomparable icomparer
我想弄清楚我需要实现哪些接口.它们基本上都做同样的事情.我何时会使用一个而不是另一个?
And*_*are 94
好吧,它们与能够比较两个不同对象的类型实现的并不完全相同,而是在能够将自己与同一类型的其他实例进行比较的类型上实现.IComparer<T>IComparable<T>
IComparable<T>当我需要知道另一个实例如何与实例相关时,我倾向于使用this. IComparer<T>对于将集合排序为IComparer<T>比较之外的看台非常有用.
Aja*_*ale 27
这取决于实体.例如,对于像"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);
}
}
Run Code Online (Sandbox Code Playgroud)
但是,如果教师'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;
}
}
Run Code Online (Sandbox Code Playgroud)
这一切都取决于你的类型是否可变.您应该只在非可变类型上实现IComparable.请注意,如果实现IComparable,则必须覆盖Equals以及==,!=,<和>运算符(请参阅代码分析警告CA1036).
从这篇博客文章中引用Dave G :
但正确的答案是,如果对象是可变的,则实现IComparer而不是IComparable,并在必要时将IComparer的实例传递给排序函数.
由于IComparer只是用于在该时间点进行排序的一次性对象,因此您的对象可以具有您想要的任何可变语义.此外,它不需要甚至建议使用Equals,GetHashCode或== - 您可以自由地以任何方式定义它.
最后,您可以为您的类型定义多个IComparer,以便在不同的字段或不同的规则上进行排序.这比坚持一个定义要灵活得多.
简而言之: 对值类型使用IComparable,对引用类型使用IComparer.
通过故事简单解释
高中篮球.这是球队的校园选择.我希望得到团队中最高/最优/最快的人.我该怎么办?
IComparer接口 - 比较两个人分开的人
Compare(Fred, John)并且它吐出了谁更好.IComparable怎么样? - 将自己与别人比较
你最近去过FB吗?你看到其他人做很酷的事情:环游世界,创造发明,而我做的事情并不那么酷 - 我们正在做的就是利用IComparable界面.
那么Comparer Class怎么样?
Comparer类是一个实现IComparer接口的抽象基类.您应该从这个类派生出具体的实现.无论如何,Microsoft建议您使用Comparer类而不是实现IComparer接口:
我们建议您从Comparer类派生而不是实现IComparer接口,因为Comparer类提供IComparer.Compare方法的显式接口实现和获取对象的默认比较器的Default属性.
希望故事能帮助你记住.