构建可比较的对象(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 接口
接口 接口是一组抽象成员的集合,表示某个类或结构可以选择去实现的行为,描述的是可属于任何类或结构的一组相关功能.接口方法的实现是在实现接口的类中完成的,实现接口的类可以显式实现该接口的成员, ...
随机推荐
- Python,遍历目录下TXT
import os #获取根目录,递归得到所以txt文件的路径 list_dirs = os.walk(os.curdir) txtfilenames=[] for root, dirs, files ...
- PLSQL Developer如何设置自动打开上次编辑的文件
作为开发人员经常把sql语句保存到文件中以方便下次继续使用,问题是plsqlDev重启后每次都需要手工打开这个文件,好不方便: 以下设置是plsqlDev启动后自动打开上次编辑的文件. 选择配置> ...
- 将Excel导入到数据中
常用的方式的有两种: 1. 通过 Microsoft.Jet.OLEDB.4.0 或 Microsoft.ACE.OLEDB.12.0 Microsoft.ACE.OLEDB.12.0 需要安装 A ...
- JavaScript Application Architecture On The Road To 2015
JavaScript Application Architecture On The Road To 2015 I once told someone I was an architect. It’s ...
- SharePoint 软件边界及限制
摘自technet http://technet.microsoft.com/zh-cn/library/cc262787.aspx
- Unity NGUI 网络斗地主 -发牌 脚本交互
Unity NGUI 网络斗地主 -发牌 脚本交互 @By 灰太龙 Unity4.2.1f4 NGUI 3.0.4 本篇说的问题是脚本与控件的交互! 现在对界面进行了改进,先看副图! 1.制作发牌效果 ...
- If one session has a shared or exclusive lock on record R in an index, another session cannot insert
If one session has a shared or exclusive lock on record R in an index, another session cannot insert ...
- Unity NGUI Tween的用法
unity版本:4.5 NGUI版本:3.6.5 参考链接:http://www.colabug.com/thread-1029974-1-1.html,作者:COLABUG.COM 橘虞 htt ...
- bzoj2789
这种题目肯定是先把一个当做标准串根据标准串得出一个初始串是怎么排列的,然后求逆序对数就可以了但是因为有重复,我们不知道标准串中的一个数到底是由原来哪个字母交换来的但是我们可以猜,不难贪心得到对于标准串 ...
- Safecracker(搜索)
http://acm.hdu.edu.cn/showproblem.php?pid=1015 / 题意; 从所给的一串字符串中选出5个字母假如是(A B C D E)使得A-B^2+C^3-D^4+E ...