构建可比较的对象(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 接口
接口 接口是一组抽象成员的集合,表示某个类或结构可以选择去实现的行为,描述的是可属于任何类或结构的一组相关功能.接口方法的实现是在实现接口的类中完成的,实现接口的类可以显式实现该接口的成员, ...
随机推荐
- github的访问变慢了
以下个人观点:把操作系统的自主研究还有处理器自主研究列入重点,还有互联网上的种种动作,我发现里面似乎揭示了某些迹象,科研真的不应该以牺牲大部分人的河法全益为代价甚至目的.当某一天win不可能出现在出厂 ...
- eclipse问题解决(maven插件link方式安装失败)
一.link方式安装eclipse的一款插件:maven (附:若不熟悉link方式,则进入此处:link方式安装eclipse插件) 其间,只弹出警告,大概意思是:部分内容,未经授权,谨慎使 ...
- Truck History(poj 1789)
Description Advanced Cargo Movement, Ltd. uses trucks of different types. Some trucks are used for v ...
- VC版本的MakeObjectInstance把WNDPROC映射到类的成员函数
这段时间用VC封装Windows类库,没有MakeObjectInstance处理窗口消息确实不爽,又不想使用MFC的消息映射,这玩意的效率和美观只能呵呵. 至于MakeObjectInstance是 ...
- Squares(哈希)
Time Limit: 3500MS Memory Limit: 65536K Total Submissions: 14328 Accepted: 5393 Description A sq ...
- Linux企业级开发技术(5)——libevent企业级开发之简介
Libevent是一个用于编写高速可移植非阻塞IO应用的库,它的设计目标是: 可移植性:使用libevent编写的程序应该可以在libevent支持的所有平台上工作.即使没有好的方式进行非阻塞IO,l ...
- LNMP搭建(CentOS 6.3+Nginx 1.2.0+PHP 5.3.15(fpm)+ MySQL 5.5.35)
Nginx (“engine x”) 是一个高性能的 HTTP 和反向代理服务器,也是一个 IMAP/POP3/SMTP 代理服务器. Nginx 是由 Igor Sysoev 为俄罗斯访问量第二的 ...
- i++和++i的老问题
对于++j,该式是指先将j的值自加1,然后再取j的值.自增过后参与计算 i的值也为10:对于i++,该表达式是指先取i的值做运算,再将i加1.参见过计算后再自增
- voronoi
- 对List
class MyCompare implements Comparator//自定义比较方式 要实现Conparator的 compare 方法 { public int compare(O ...