构建可比较的对象(IComparable)
IComparable接口
System.IComparable接口指定了一种允许一个对象可基于某些特定键值进行排序的行为。
namespace System
{
[ComVisible(true)]
public interface IComparable
{
int CompareTo(object obj);
}
}
CompareTo()方法背后的逻辑是,根据某个特定数据字段比较传入的对象与当前实例。CompareTo()方法的返回值被用来判断这个类型小于、大于或是等于它所比较的对象。
- 任何小于0的数字:这个实例在指定对象之前
- 0:这个实例等于指定对象
- 任何大于0的数字:这个实例在指定对象之后
构建可比较对象
System.Array类定义了一个名为 Sort()的静态方法。在内置类型(int、short、string等)上调用这个方法的时候,可以以数字/字母顺序对数组中的项排序,因为这些内置数据类型实现了IComparable。
构建可排序的Car类型
namespace ComparableCar
{
class Car : IComparable
{
public int CurrentSpeed { get; set; }
public string PetName { get; set; }
public int CarID { get; set; }
public Car() { } public Car( string name, int currSp, int id )
{
CurrentSpeed = currSp;
PetName = name;
CarID = id;
} int IComparable.CompareTo(object obj)
{
Car temp = obj as Car;
if (temp != null)
{
if (this.CarID > temp.CarID)
return ;
if (this.CarID < temp.CarID)
return -;
else
return ;
}
else
throw new ArgumentException("Parameter is not a Car!");
}
}
}
由于C#int数据类型(只是CLR System.Int32的简写形式)实现了IComparable,我们就可以按如下所示的方法实现ICompareTo()方法:
int IComparable.CompareTo( object obj )
{
Car temp = obj as Car;
if (temp != null)
return this.CarID.CompareTo(temp.CarID);
else
throw new ArgumentException("Parameter is not a Car!");
}
Car类型已经知道如何将它自己和类似对象进行对比:
namespace ComparableCar
{
class Program
{
static void Main( string[] args )
{
Console.WriteLine("***** Fun with Object Sorting *****\n");
Car[] myAutos = new Car[];
myAutos[] = new Car("Rusty", , );
myAutos[] = new Car("Mary", , );
myAutos[] = new Car("Viper", , );
myAutos[] = new Car("Mel", , );
myAutos[] = new Car("Chucky", , ); Console.WriteLine("Here is the unordered set of cars:");
foreach (Car c in myAutos)
Console.WriteLine("{0} {1}", c.CarID, c.PetName); Array.Sort(myAutos);
Console.WriteLine(); Console.WriteLine("Here is the ordered set of cars:");
foreach (Car c in myAutos)
Console.WriteLine("{0} {1}", c.CarID, c.PetName); Console.ReadLine();
}
}
}

指定多个排序顺序IComparer
如果要构建一个既可通过ID排序又可通过昵称排序的Car类型,就需要与另一个标准接口IComparer打交道。
namespace System.Collections
{
[ComVisible(true)]
public interface IComparer
{
int Compare(object x, object y);
}
}
与IComparable接口不同,IComparer接口不是在要排序的类型(即Car)中,而是在许多辅助类中实现的,其中每个排序各有一个依据(如昵称、ID号等)。
namespace ComparableCar
{
// 这个辅助类用来通过昵称排序Car类型的数组
public class PetNameComparer : IComparer
{
// 测试每个对象的昵称
int IComparer.Compare( object o1, object o2 )
{
Car t1 = o1 as Car;
Car t2 = o2 as Car;
if (t1 != null && t2 != null)
return String.Compare(t1.PetName, t2.PetName);
else
throw new ArgumentException("Parameter is not a Car!");
}
}
}
System.Array有许多重载的Sort()方法,其中有一个用来在对象上实现IComparer接口。
namespace ComparableCar
{
class Program
{
static void Main( string[] args )
{
...
// 按照昵称进行排序
Array.Sort(myAutos, new PetNameComparer()); Console.WriteLine("Ordering by pet name:");
foreach (Car c in myAutos)
Console.WriteLine("{0} {1}", c.CarID, c.PetName);
...
}
}
}
自定义属性、自定义排序类型
值得指出的是,在通过特定数据字段排序Car类型的时候,可以使用自定义的静态属性辅助对象用户。假定Car类型添加了一个静态只读属性SortByPetName,它返回一个实现了IComparer接口的对象的实例(在本例中为PetNameComparer):
namespace ComparableCar
{
// 现在可以使用一个自定义静态属性来返回正确的IComparer接口
class Car : IComparable
{
...
// 返回SortByPetName比较的属性
public static IComparer SortByPetName
{ get { return (IComparer)new PetNameComparer(); } }
...
}
}
现在可以使用强关联属性按照昵称排序,而不是只能使用独立的PetNameComparer类型:
// 简洁明了的按照昵称排序
Array.Sort(myAutos, Car.SortByPetName);
构建可比较的对象(IComparable)的更多相关文章
- WPF整理-XAML构建后台类对象
1.XAML 接触WPF的第一眼就是XAML---XAML是用来描绘界面的.其实不然! "Actually, XAML has nothing to do with UI. It's mer ...
- 从零构建JavaScript的对象系统
一.正统的类与继承 类是对象的定义,而对象是类的实例(Instance).类不可直接使用,要想使用就必须在内存上生成该类的副本,这个副本就是对象. 以Java为例: public class Grou ...
- Android开发 ---构建对话框Builder对象,消息提示框、列表对话框、单选提示框、多选提示框、日期/时间对话框、进度条对话框、自定义对话框、投影
效果图: 1.activity_main.xml 描述: a.定义了一个消息提示框按钮 点击按钮弹出消息 b.定义了一个选择城市的输入框 点击按钮选择城市 c.定义了一个单选提示框按钮 点击按钮选择某 ...
- JS批量获取参数构建JSON参数对象
在做系统的时候,往往查询条件是被严格指定的,大量的查询条件,一两个页面还可以通过dom去一个一个获取,再构建参数对象,请求后台接口. 这里给大家讲一个批量获取前端参数,构建参数对象. <form ...
- 使用SQL联合查询来构建临时vo对象的应用
联合查询: 表1: team球队表 表2:schedule 赛程表 需要数据: 球队名称.主队ID.主队名称.客队ID.客队名称.胜负情况 方法1. Object数组取出列和数值 import jav ...
- spring mvc 利用匿名内部类构建返回json对象
@RequestMapping(value = "/order/findOrderByIdVague/{noId}.json", method = {RequestMethod.G ...
- 调用的方法里接收一个List<>类型的参数,里面是自定义的EC类, 我要通过反射构建这List对象
public static object CreateGeneric(Type generic, Type innerType, params object[] args) ...
- 精通C#(第6版)
<精通C#(第6版)> 基本信息 原书名:Pro C# 5.0 and the .NET 4.5 framework,sixth edition 作者: (美)Andrew Troelse ...
- .NET 接口
接口 接口是一组抽象成员的集合,表示某个类或结构可以选择去实现的行为,描述的是可属于任何类或结构的一组相关功能.接口方法的实现是在实现接口的类中完成的,实现接口的类可以显式实现该接口的成员, ...
随机推荐
- (转载)50个c/c++源代码网站
C/C++是最主要的编程语言.这里列出了50名优秀网站和网页清单,这些网站提供c/c++源代码.这份清单提供了源代码的链接以及它们的小说明.我已 尽力包括最佳的C/C++源代码的网站.这不是一个完整的 ...
- BZOJ 1005 明明的烦恼
Description 自从明明学了树的结构,就对奇怪的树产生了兴趣...... 给出标号为1到N的点,以及某些点最终的度数,允许在任意两点间连线,可产生多少棵度数满足要求的树? Input 第一行为 ...
- LINUX HA:Pacemaker + Corosync初配成功
参考很多文档: http://zhumeng8337797.blog.163.com/blog/static/100768914201218115650522/ 下一步,想想这个PC组和与HAPROX ...
- PlatformTransactionManager
Spring Boot 使用事务非常简单,首先使用注解 @EnableTransactionManagement 开启事务支持后,然后在访问数据库的Service方法上添加注解 @Transactio ...
- 第二章 Stream API
引例: 1 List<String> strList = Arrays.asList("zhaojigang","nana","tiany ...
- Lua开发环境配置
Lua(英语发音:/ˈluːə/)程序设计语言是一个简洁.轻量.可扩展的脚本语言,是葡萄牙语中“Luna”(月亮)的意思. Lua is a powerful, fast, lightweight, ...
- a great tool for automatically formating your code!
1. make your own format file at your project's root or file's folder. (The clang-format will automat ...
- CentOS squid代理内网主机上网 openVpn配置
- 西安Uber优步司机奖励政策(1月11日~1月17日)
滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...
- [IE9] GPU硬件加速
IE9 的一个重大改进就是使用了GPU硬件加速来渲染网页. 那么GPU硬件加速到底能够带来多大的性能提升? 你可以在IE的测试案例网站(http://ie.microsoft.com/testdr ...