C# IComparable接口、IComparer接口和CompareTo(Object x)方法、Compare()方法

在项目中经常会用到字符串比较,但是有时候对字符串的操作比较多,规则各异。比如有的地方我们需要用排序规则,有的地方需要忽略大小写,我们该如何写一个比较容易操作的比较方法呢?重新实现IComparer接口不失为一个好办法。

IComparable.CompareTo 方法

在MSDN上是这么解释(机器翻译过来)的:

IComparable接口:定义一种特定于类型的通用比较方法,值类型或类通过实现此方法对其实例进行排序。

IComparer接口:公开一种比较两个对象的方法。

详细理解就是:

在默认情况下,对象的Equals(object o)方法(基类Object提供),是比较两个对象变量是否引用同一对象。

我们要必须我们自己的对象,必须自己定义对象比较方式。

IComparable和ICompare 接口是.net framework 中比较对象的标准方式,这两个接口之间的区别如下:

IComparable是标识这个类型具有比较的能力,可以比较该对象和另一个对象。一般情况下,我们使用 IComparable 给出类的默认比较代码,使用其他类给出非默认的比较代码。中文应该叫“可比较对象”。

IComparer是在一个单独的类中实现,是指当前对象可以用来比较任意两个对象,而当前对象本身不参与计算,中文应该叫“比较器”。

CompareTo:IComparable提供了一个方法int CompareTo(object obj)。这个方法接受一个对象,将当前实例的对象与同一类型的另一个对象进行比较,并返回一个整数,该整数指示当前实例在排序顺序中的位置是位于另一个对象之前、之后还是与其位置相同。

Compare:IComparer 也提供了一个方法 Compare().这个方法接受两个对象,返回一个整型结果,这与 CompareTo()相同。

IComparable接口

比如:有一个默认实例对象person1,需要和person2判断,判断person1是否比person2更年老或年轻,实际上,这个方法返回一个int,所以可和下面的代码说明person1更年老还是更年轻。

 1  if(person1.CompareTo(person2) == 0)
 2  2 {
 3  3   Console.WriteLine("Same age");//年龄一样,person1和person2比较后返回0
 4  4 }
 5  5 else if(person1.CompareTo(person2) > 0 )
 6  6 {
 7  7   Console.WriteLine("person1 is older");//如果person1>person2,person1和person2比较后返回正整数,person1比person2年龄大
 8  8 }
 9  9 else
10 10 {
11 11   Console.WriteLine("person1 is younger");//如上述if不成立,person1<person2,person1和person2比较后返回正整数,person1比person2年龄小
12 12 }

IComparer接口

同样适用person来做例子

比如:有一个对象person1,需要和person2判断,判断person1是否比person2更年老或年轻,实际上,这个方法同样也是返回一个int,但是我们使用的是另外的接口(IComparer)的Compare来写,所以可和下面的代码说明person1更年老还是更年轻。

 1 if(personComparer.Compare(person1,person2) == 0)
 2 {
 3   Console.WriteLine("same age");
 4 }
 5 else if(personComparer.Compare(person1,person2) > 0 )
 6 {
 7   Console.WriteLine("person 1 is older");
 8 }
 9 else
10 {
11   Console.WriteLine("person1 is younger");
12 }

在这两种情况下,提供给方法的参数(person1、person2)是system.object类型。也就是说,可以比较任意类型的两个对象。所以,在返回结果之前,通常需要进行某种类型比较,如果使用了错误的类型,还会抛出异常。实际上,我们是使用泛型接口IComparable<T>,可以省略对象转换。

对象之间的大小比较,在开发过程中用的还是很多的,比如:string是一个可比较对象,它具有和另外一个String比较的能力,它会使用字母序进行比较。但是,有时候我们的一些逻辑需要一些特殊的比较方法。例如:WindowsExplorer 中的文件排序会认为”File10.txt" > "File2.txt"。这时候,我们就需要写一个特殊的IComparer对象实现这些特定的逻辑。

-----------------------------------------------------------------------------分割线-----------------------------------------------------------------------------

IComparable.CompareTo(Object x)的比较方式:

compareTo()的返回值是整型类型,它是先比较对应字符的大小(ASCII码顺序),如果第一个字符和另一个参数的第一个字符不等,结束比较,返回他们ASCII码之间的差值,如果第一个字符和另一个参数的第一个字符相等,则以第二个

字符和另一个参数的第二个字符做比较,以此类推,直至比较的字符或被比较的字符有一方全比较完,这时就比较字符的长度.

举个Java的例子说明:

String s1 = "abc"; 
String s2 = "abcd"; 
String s3 = "abcdefg"; 
String s4 = "1bcdfg"; 
String s5 = "cdfg"; 
System.out.println( s1.compareTo(s2) ); // -1 (前面相等,s1长度小1) 
System.out.println( s1.compareTo(s3) ); // -4 (前面相等,s1长度小4) 
System.out.println( s1.compareTo(s4) ); // 48 ("a"的ASCII码是97,"1"的的ASCII码是49,所以返回48) 
System.out.println( s1.compareTo(s5) ); // -2 ("a"的ASCII码是97,"c"的ASCII码是99,所以返回-2)

-----------------------------------------------------------------------------分割线-----------------------------------------------------------------------------

C# 如何实现compareTo()方法

那么在什么时候使用Icomparable.CompareTo(object obj)方法呢?

如果一个类实现了Icomparable接口,就可以重写Icomparable接口中的CompareTo(object obj)方法,假设集合中有几个学员对象,要按学员的姓名进行排序,那么就可以重写CompareTo方法按姓名排序,但如果又想按年龄排序了怎么办?CompareTo方法只能重写一次啊,这时就可以用到Icompare了。Icompare就叫做比较器,集合默认的Sort()排序方法有种重载的参数就是Icompare比较器对象。

像所有集合类一样,它允许您对所有实现了IComparable接口的对象进行排序。在下一个例子中,您将修改NameCompare类以实现IComparable的泛型接口:

public class NameCompare: IComparable<Student>

实现IComparable<Student>接口,NameCompare对象必须提供CompareTo()方法:

 1 class NameCompare:IComparer<Student>     //姓名升序
 2 {
 3    public int Compare(Student x, Student y)
 4    {
 5         return x.Name.CompareTo(y.Name);
 6    }
 7 }
 8
 9 class NameCompare1 : IComparer<Student>     //姓名降序
10 {
11     public int Compare(Student x, Student y)
12     {
13         return y.Name.CompareTo(x.Name);
14     }
15 }
16
17 class AgeCompare : IComparer<Student>
18 {
19     public int Compare(Student x, Student y)
20     {
21         return x.Age.CompareTo(y.Age);
22     }
23 }

要排序的时候:

private void button3_Click(object sender, EventArgs e)
{
    init();
    students.Sort(new NameCompare());               //姓名升序,Sort方法的参数就是实现了Icompare接口的类的对象
    show(students);
}

private void button4_Click(object sender, EventArgs e)
{
    init();
    students.Sort(new NameCompare1());          //姓名降序
    show(students);
}

private void button5_Click(object sender, EventArgs e)
{
    init();
    students.Sort(new AgeCompare());
    show(students);
}

转发请说明出处:http://www.cnblogs.com/abc1069/p/3993818.html

时间: 2024-12-15 22:24:53

C# IComparable接口、IComparer接口和CompareTo(Object x)方法、Compare()方法的相关文章

对象的比较与排序:IComparable和IComparer接口

IComparable和ICompare 接口是.net framework 中比较对象的标准方式,这两个接口提供一个返回值类似(大于0 等于0 小于0)的比较方法,二者区别如下: 1. IComparable 在要比较的对象的类中实现,可以比较该对象和另一个对象. 2. IComparer 在一个单独的类中实现,可以比较任意两个对象. 先看 IComparable 这个接口方法是 int CompareTo(object obj); 方法只有一个参数,我们知道比较至少要有两个对象,所以这个方法

IComparable和IComparer接口

C#中,自定义类型,支持比较和排序,需要实现IComparable接口.IComparable接口存在一个名为CompareTo()的方法,接收类型为object的参数表示被比较对象,返回整型值:1表示当前对象大于被比较对象,0表示两者相等,-1表示当前对象小于被比较对象. public int CompareTo(object o) {} 若想以更加灵活的方式对自定义类进行比较,可以声明一个继承自IComparer接口的比较器,实现接口方法Comprae(),接收2个object类型参数作为比

IComparable和IComparer接口的简析

默认情况下,对象的Equals(object o)方法是比较两个对象是否引用同一个对象.如果我们有自己的对象,就要自己定义对象比较方式: 1.IComparable在要比较的对象(类的实例化就是对象)类中实现,可以比较该对象和另一个对象. 2.IComparer在一个单独的类中实现,可以任意比较两个对象. 通俗的讲,IComparable是能够比较,具备比较的能力.比如说某个人具备编程的能力,如果需要对编程能力的高低进行比较的话,就必须在自己的类中去实现怎么具体的方法.IComparer是比较者

实现IComparable、IComparer接口

using System;using System.Collections.Generic; public class MyClass{ public class Employee:IComparable<Employee> { public int EmpID; public string YearsOfSvc = "1"; public Employee(int id) { EmpID = id; } public Employee(int id , string ys

c# IComparable与IComparer接口

原文地址:https://www.cnblogs.com/fanweisheng/p/11517698.html

IComparable和IComparer 区别

在默认情况下,对象的Equals(object o)方法(基类Object提供),是比较两个对象变量是否引用同一对象. 我们要必须我自己的对象,必须自己定义对象比较方式. IComparable和ICompare 接口是.net framework 中比较对象的标准方式,这两个接口之间的区别如下: 1. IComparable 在要比较的对象的类中实现,可以比较该对象和另一个对象. 2.IComparer 在一个单独的类中实现,可以比较任意两个对象. 一般情况下,我们使用 IComparable

C# 常用接口学习 IComparable 和 IComparer

作者:乌龙哈里 时间:2015-11-01 平台:Window7 64bit,Visual Studio Community 2015 参考: Microsoft Refernce Souce MSDN 章节: 接口 IConmparable 实现 接口 IComparable<T> 实现 接口 IComparer<T> 实现 正文: 一.接口 IConmparable 的实现 class Fruit {     public string Name;     public int

IComparable类型排序接口

// 摘要: //     定义一种特定于类型的通用比较方法,值类型或类通过实现此方法对其实例进行排序. [ComVisible(true)] public interface IComparable { // 摘要: //     将当前实例与同一类型的另一个对象进行比较,并返回一个整数,该整数指示当前实 //例在排序顺序中的位置是位于另一个对象之前.之后还是与其位置相同. // // 参数: //   obj: //     与此实例进行比较的对象. // // 返回结果: //     一

关于comparator接口和comparable接口以及它们各自的方法compare()和compareTo()

在今天做的LeetCode的题中有两道都出现了利用接口实现对象的排序,两题的相关链接: 1.利用comparable接口对对象排序 2.利用comparator接口实现排序 由于之前都没接触过这两个接口,一时不能明白它们的作用,所以在网上查找了很多资料,现在大致弄清楚一些,现在记录下来,有什么欠缺,欢迎大家及时指正 1.Comparable<T>接口 在java API文档中描述此接口是强行将实现它的每一个类的对象进行整体排序-----称为该类的自然排序,实现此接口的对象列表和数组可以用Col