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更年老还是更年轻。
if(person1.CompareTo(person2) == )
{
Console.WriteLine("Same age");//年龄一样,person1和person2比较后返回0
}
else if(person1.CompareTo(person2) > )
{
Console.WriteLine("person1 is older");//如果person1>person2,person1和person2比较后返回正整数,person1比person2年龄大
}
else
{
Console.WriteLine("person1 is younger");//如上述if不成立,person1<person2,person1和person2比较后返回正整数,person1比person2年龄小
}
IComparer接口
同样适用person来做例子
比如:有一个对象person1,需要和person2判断,判断person1是否比person2更年老或年轻,实际上,这个方法同样也是返回一个int,但是我们使用的是另外的接口(IComparer)的Compare来写,所以可和下面的代码说明person1更年老还是更年轻。
if(personComparer.Compare(person1,person2) == )
{
Console.WriteLine("same age");
}
else if(personComparer.Compare(person1,person2) > )
{
Console.WriteLine("person 1 is older");
}
else
{
Console.WriteLine("person1 is younger");
}
在这两种情况下,提供给方法的参数(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()方法:
class NameCompare:IComparer<Student> //姓名升序
{
public int Compare(Student x, Student y)
{
return x.Name.CompareTo(y.Name);
}
} class NameCompare1 : IComparer<Student> //姓名降序
{
public int Compare(Student x, Student y)
{
return y.Name.CompareTo(x.Name);
}
} class AgeCompare : IComparer<Student>
{
public int Compare(Student x, Student y)
{
return x.Age.CompareTo(y.Age);
}
}
要排序的时候:
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
C# IComparable接口、IComparer接口和CompareTo(Object x)方法、Compare()方法的更多相关文章
- c# 实现IComparable、IComparer接口、Comparer类的详解
在默认情况下,对象的Equals(object o)方法(基类Object提供),是比较两个对象变量是否引用同一对象.我们要必须我自己的对象,必须自己定义对象比较方式.IComparable和ICom ...
- [0] 关于IComparable和IComparer接口和Comparer类
关于IComparable和IComparer接口 和 Comparer类 IComparable和ICompareframeworkr接口是.net 中比较对象的标准方式,这两个接口之间的区别如下: ...
- 对象的比较与排序:IComparable和IComparer接口
IComparable和ICompare 接口是.net framework 中比较对象的标准方式,这两个接口提供一个返回值类似(大于0 等于0 小于0)的比较方法,二者区别如下: . ICompar ...
- C#中的IComparable 和 IComparer 接口,实现列表中的对象比较和排序
借豆瓣某博主的话先对这两个接口进行一个解释: IComparable在要比较的对象的类中实现,可以比较该对象和另一个对象 IComparer在一个单独的类中实现,可以比较任意两个对象. 如果已经支持 ...
- IComparable和IComparer接口
C#中,自定义类型,支持比较和排序,需要实现IComparable接口.IComparable接口存在一个名为CompareTo()的方法,接收类型为object的参数表示被比较对象,返回整型值:1表 ...
- 数组自定义排序:IComparable和IComparer接口
首先先说一下IComparable和IComparer的区别,前者必须在实体类中实现,后者可以单独出现在一个排序类中,即此类只包含一个compare方法. Array类使用快速算法对数组中的元素进行排 ...
- C#的 IComparable 和 IComparer接口及ComparableTo方法的 区别(非常重要)
(1)https://blog.csdn.net/ios99999/article/details/77800819 C# IComparable 和 IComparer 区别 (2)https:// ...
- 实现IComparable、IComparer接口
using System;using System.Collections.Generic; public class MyClass{ public class Employee:IComparab ...
- c# IComparable与IComparer接口
随机推荐
- QQ传输协议分析
2015-06-16 16:27:07 一. 实验目的: 在虚拟机下NAT模式下通过Wireshark抓包,分析QQ的传输模式.了解QQ在传输信息过程中用到的协议.分析在Nat模式下,信息传输的穿透性 ...
- 1226关于count(*)不走主键索引反而走二级索引
转自 http://www.2cto.com/database/201508/433975.html mysqlcount(*)会选哪个索引? 2015-08-19 0个评论 来源:D ...
- JavaEE学习文章汇总-ssm框架
Spring-SpringMVC-Mybatis 1:Maven创建webapp项目 Maven 下的spring框架(一创建项目) 2:mybatis3 入门教程 mybatis实战教程(mybat ...
- shell及脚本2——shell 环境及命令
一.快捷键.通配符.特殊符号 1. 快捷键 CTRL+C:终止目前的命令 CTRL+D:输入结束,EOF CTRL+M:ENTER CTRL+S:暂停屏幕输出 CTRL+Q:恢复屏幕输出 CTRL+U ...
- 用libcurl 登录网站
libcurl 可以发送和接收HTTP消息,因此可以发送用户名.密码和验证码来登录网站,网上有不少这方面的内容,但不甚完整,我摸索了两天,将其中要点记录下来. 基本步骤 正常访问登录页面,访问时,设置 ...
- grails 优缺点分析
Grails是一套用于快速Web应用开发的开源框架,它基于Groovy编程语言,并构建于Spring.Hibernate等开源框架之上,是一个高生产力一站式框架. 易于使用的基于Hibernate的对 ...
- py-faster-rcnn几个辅助脚本
py-faster-rcnn本身代码很棒. 不过使用它的时候,还是需要自己写一些脚本,作为辅助. 1 所有.py文件顶部添加utf8编码声明.因为有时候需要添加中文注释,不声明编码会报错 #inser ...
- BZOJ1192 [HNOI2006]鬼谷子的钱袋
本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000 作者博客:http://www.cnblogs.com/ljh2000-jump/ ...
- 【Beta】Scrum06
Info 时间:2016.12.15 21:35 时长:25min 地点:大运村1号公寓5楼楼道 类型:日常Scrum会议 NXT:2016.12.17 21:30 Task Report Name ...
- 16 Promise
Promise 特点 对象的状态不受外界影响.Promise对象代表一个异步操作,有三种状态:Pending(进行中).Resolved(已完成,又称Fulfilled)和Rejected(已失败). ...