C# 常用接口学习 IComparable 和 IComparer
C# 常用接口学习 IComparable 和 IComparer
作者:乌龙哈里
时间:2015-11-01
平台:Window7 64bit,Visual Studio Community 2015
参考:
章节:
- 接口 IConmparable 实现
- 接口 IComparable<T> 实现
- 接口 IComparer<T> 实现
正文:
一、接口 IConmparable 的实现
class Fruit
{
public string Name;
public int Price;
}
List<Fruit> fruit = new List<Fruit>();
fruit.Add(new Fruit { Name = "grape", Price = 30 });
fruit.Add(new Fruit { Name = "apple", Price = 10 });
fruit.Add(new Fruit { Name = "banana", Price = 15 });
fruit.Add(new Fruit { Name = "orage", Price = 12 });
我们如果想要把水果类按价钱排序,用 Sort() 方法,就需要在 Fruit 类实现 IComparable 接口了。
去看了net4.0的公开源代码(见参考),只有一个方法:
int CompareTo(Object obj);
微软的技术人员在注释里说明了,等于返回0值,大于返回大于0的值,小于返回小于0的值。下面我们按说明来实现这个接口:
class Fruit : IComparable
{
public string Name;
public int Price;
public int CompareTo(object obj)
{
//实现接口方法一:
if (obj == null) return 1;
Fruit otherFruit = obj as Fruit;
if (Price > otherFruit.Price) { return 1; }
else
{
if (Price == otherFruit.Price) { return 0; }
else { return -1; }
}
}
}
测试 Sort() 输出:
static void Main(string[] args)
{
List<Fruit> fruit = new List<Fruit>();
fruit.Add(new Fruit { Name = "grape", Price = 30 });
fruit.Add(new Fruit { Name = "apple", Price = 10 });
fruit.Add(new Fruit { Name = "banana", Price = 15 });
fruit.Add(new Fruit { Name = "orage", Price = 12 });
Console.Write("未排序:");
foreach (var f in fruit) Console.Write($"{f.Name} ");
Console.WriteLine();
fruit.Sort();
Console.Write("排序后:");
foreach (var f in fruit) Console.Write($"{f.Name} ");
Console.WriteLine();
Console.ReadKey();
}
//输出结果:
//未排序:grape apple banana orage
//排序后:apple orage banana grape
要是要按照 Name 来排序,只要把 Price 换成 Name就成了。
我们发现,所有的简单值类型(比如:int ,string 等等)都继承了这个 IComparable 接口的,我们可以借用值类型的 CompareTo() 方法来实现:
class Fruit : IComparable
{
public string Name;
public int Price;
public int CompareTo(object obj)
{
//实现接口方法二:
Fruit otherFruit = obj as Fruit;
return Price.CompareTo(otherFruit.Price);
}
}
对于这个 IComparable 接口,因为基本简单的值类型都有 CompareTo() 方法,而且有了 Linq 后,我只要能用 IEnumerable<T> 的集合类型,用 lambda 表达式很容易就能进行排序 Sort() 操作,而且升序降序排序更加方便。上面的例子中,就算 Fruit 类没有实现 IComparable 接口,我用 List<T>,然后用 lambda 表达式生成一个新的集合就成了,如下:
class Program
{
static void Main(string[] args)
{
List<Fruit> fruit = new List<Fruit>();
fruit.Add(new Fruit { Name = "grape", Price = 30 });
fruit.Add(new Fruit { Name = "apple", Price = 10 });
fruit.Add(new Fruit { Name = "banana", Price = 15 });
fruit.Add(new Fruit { Name = "orage", Price = 12 });
Console.Write("排序前:");
foreach (var f in fruit) Console.Write($"{f.Name} ");
Console.WriteLine();
var fruitSort = fruit.OrderBy(x => x.Price);
Console.Write("排序后:");
foreach (var f in fruitSort) Console.Write($"{f.Name} ");
Console.WriteLine();
Console.ReadKey();
}
}
class Fruit
{
public string Name;
public int Price;
}
真的弄不清楚到底这个接口有了泛型和 Linq 后还有什么用。本着认真学习的态度,我们继续学习它的泛型接口。
二、接口 IConmparable<T> 的实现
我们看到在实现 IComparable 中会发生装箱行为:
Fruit otherFruit=obj as Fruit;
为了效率就引进了泛型,实现如下:
class Fruit : IComparable<Fruit>
{
public string Name;
public int Price;
int IComparable<Fruit>.CompareTo(Fruit other)
{
return Price.CompareTo(other.Price);
}
}
调用和普通的一样调用。现在还有个一问题,就是我们在章节一里面所说的,这个 Fruit 类是按字段 Price 来排序的,要是我们想按 Name 来排序,修改 int CompareTo() 方法很不灵活和方便,这时我们就需要另外一个类似的接口 IComparer 来提供便利了。
三、接口 IConmparer<T> 的实现
这个 IComparer 我理解为比较器接口,章节一的 Fruit 类接口 IComparable 不改,要想按 Name 来排序,需创立一个新类,在其上实现 IComparer<T> 接口:
class SortByName : IComparer<Fruit>
{
int IComparer<Fruit>.Compare(Fruit x, Fruit y)
{
return x.Name.CompareTo(y.Name);
}
}
class Fruit : IComparable
{
public string Name;
public int Price;
public int CompareTo(object obj)
{
//实现接口方法二:
Fruit otherFruit = obj as Fruit;
return Price.CompareTo(otherFruit.Price);
}
}
调用: fruit.Sort(new SortByName());
这个接口给我们带来重大的灵活性和方便性。不过我还是认为在泛型和lambda范式后,这个玩意好像真的没多大用处。
本文到此结束。
题外话:C#真的是一门优雅优秀的语言,而且微软开放了部分源代码,值得长期投资。
C# 常用接口学习 IComparable 和 IComparer的更多相关文章
- C# 常用接口学习 ICollection<T>
C# 常用接口学习 ICollection<T> 作者:乌龙哈里 时间:2015-11-01 平台:Window7 64bit,Visual Studio Community 2015 参 ...
- C# 常用接口学习 IEnumerable<T>
作者:乌龙哈里 时间:2015-10-24 平台:Window7 64bit,Visual Studio Community 2015 本文参考: MSDN IEnumerable<T> ...
- 常用接口简析2---IComparable和IComparer接口的简析
常用接口的解析(链接) 1.IEnumerable深入解析 2.IEnumerable.IEnumerator接口解析 3.IList.IList接口解析 默认情况下,对象的Equals(object ...
- 数组自定义排序:IComparable和IComparer接口
首先先说一下IComparable和IComparer的区别,前者必须在实体类中实现,后者可以单独出现在一个排序类中,即此类只包含一个compare方法. Array类使用快速算法对数组中的元素进行排 ...
- [0] 关于IComparable和IComparer接口和Comparer类
关于IComparable和IComparer接口 和 Comparer类 IComparable和ICompareframeworkr接口是.net 中比较对象的标准方式,这两个接口之间的区别如下: ...
- IComparable和IComparer接口
C#中,自定义类型,支持比较和排序,需要实现IComparable接口.IComparable接口存在一个名为CompareTo()的方法,接收类型为object的参数表示被比较对象,返回整型值:1表 ...
- JDBC 学习笔记(三)—— JDBC 常用接口和类,JDBC 编程步骤
1. JDBC 常用接口和类 DriverManager 负责管理 JDBC 驱动的服务类,程序中主要的功能是获取连接数据库的 Connection 对象. Connection 代表一个数据库连接对 ...
- C#的 IComparable 和 IComparer接口及ComparableTo方法的 区别(非常重要)
(1)https://blog.csdn.net/ios99999/article/details/77800819 C# IComparable 和 IComparer 区别 (2)https:// ...
- 常用接口简析3---IList和List的解析
常用接口的解析(链接) 1.IEnumerable深入解析 2.IEnumerable.IEnumerator接口解析 3.IComparable.IComparable接口解析 学习第一步,先上菜: ...
随机推荐
- 搭建Ubuntu12.04交叉编译服务器
最近在公司学着搭建一台Linux服务器作为交叉编译的主机之用,服务器端选择了Ubuntu12.04 LTS桌面版,客户端采用Windows XP平台,使用SSH工具软件putty登录到Linux主机, ...
- HNCU1324:算法2-2:有序线性表的有序合并(线性表)
http://hncu.acmclub.com/index.php?app=problem_title&id=111&problem_id=1324 题目描述 已知线性表 LA 和 L ...
- 开发一个微信小程序教程
一.注册小程序账号 1.进入微信公众平台(https://mp.weixin.qq.com/),注册小程序账号,根据提示填写对应的信息即可. 2.注册成功后进入首页,在 小程序发布流程->小程序 ...
- ClassLoader的等级加载机制
摘自深入分析java web技术内幕
- windows下练习linux shell
<---开始学习linux---记录一下---路漫漫其修远兮---加油吧---萌萌达> 使用软件:Cygwin 下载地址(免安装版):链接: http://pan.baidu.com/s ...
- Android自定义控件系列(二)—icon+文字的多种效果实现
转载请注明出处:http://www.cnblogs.com/landptf/p/6290810.html 今天给大家带来一个很简单但是很常用的控件ButtonExtendM,在开发中我们经常会用到图 ...
- 疑问:关于postgres的to_number()
postgres中的to_number(text,number),即是把字符串text转为number的函数,但有时候用的时候经常碰到这样的错误:[Err] ERROR: invalid input ...
- openstack-kilo--issue(十二)openstack-keystone和httpd服务同时占用35357和5000
== Keystone service == openstack-keystone: inactive 如上面显示的状态:如果启动了httpd就不能很好的启动openstack-keystone服务, ...
- Nexpose
下载: https://www.rapid7.com/products/nexpose/nexpose-enterprise-trial-thank-you.jsp注册: https://www.ra ...
- Zabbix-agent使用自带模板监控 MySQL
1.rpm -ivh http://repo.zabbix.com/zabbix/2.4/rhel/6/x86_64/zabbix-release-2.4-1.el6.noarch.rpm 2.yum ...