Effective C# 原则26:用IComparable和IComparer实现对象的顺序关系
2009-02-19 08:16:22 来源:WEB开发网你的类型应该有一个顺序关系,以便在集合中描述它们如何存储以及排序。.Net框架为你提供了两个接口来描述对象的顺序关系:IComparable 和IComparer。IComparable 为你的类定义了自然顺序,而实现IComparer接口的类可以描述其它可选的顺序。你可以在实现接口时,定义并实现你自己关系操作符(<,>,<=,>=),用于避免在运行时默认比较关系的低效问题。这一原则将讨论如何实现顺序关系,以便.Net框架的核心可以通过你定义的接口对你的类型进行排序。这样用户可以在些操作上得更好的效率。
IComparable接口只有一个方法:CompareTo(),这个方法沿用了传统的C函数库里的strcmp函数的实现原则:如果当前对象比目标对象小,它的返回值小于0;如果相等就返回0;如果当前对象比目标对象大,返回值就大于0。IComparable以System.Object做为参数,因此在使用这个函数时,你须要对运行时的对象进行检测。每次进行比较时,你必须重新解释参数的类型:
public struct Customer : IComparable
{
private readonly string _name;
public Customer( string name )
{
_name = name;
}
#region IComparable Members
public int CompareTo( object right )
{
if ( ! ( right is Customer ) )
throw new ArgumentException( "Argument not a customer",
"right" );
Customer rightCustomer = ( Customer )right;
return _name.CompareTo( rightCustomer._name );
}
#endregion
}
关于实现比较与IComparable接口的一致性有很多不太喜欢的地方,首先就是你要检测参数的运行时类型。不正确的代码可以用任何类型做为参数来调用CompareTo方法。还有,正确的参数还必须进行装箱与拆箱后才能提供实际的比较。每次比较都要进行这样额外的开销。在对集合进行排序时,在对象上进行的平均比较次数为N x log(N),而每次都会产生三次装箱与拆箱。对于一个有1000个点的数组来说,这将会产生大概20000次的装箱与拆箱操作,平均计算:N x log(n) 有7000次,每次比较有3次装箱与拆箱。因此,你必须自己找个可选的比较方法。你无法改变IComparable.CompareTo()的定义,但这并不意味着你要被迫让你的用户在一个弱类型的实现上也要忍受性能的损失。你可以重载CompareTo()方法,让它只对Customer 对象操作:
Tags:Effective 原则 IComparable
编辑录入:爽爽 [复制链接] [打 印]- ››Effective C# 原则40:根据需求选择集合
- ››Effective C# 原则41:选择DataSet而不是自定义的...
- ››Effective C# 原则42:使用特性进行简单的反射
- ››Effective C# 原则43:请勿滥用反射
- ››Effective C# 原则44:创建应用程序特定的异常类
- ››Effective C# 第6章:杂项
- ››Effective C# 原则45:选择强异常来保护程序
- ››Effective C# 原则47:选择安全的代码
- ››Effective C# 原则48:了解更多的工具和资源
- ››Effective C# 原则49:为C#2.0做好准备
- ››Effective C# 原则50:了解ECMA标准
- ››Effective C# 原则系列文章目录
更多精彩
赞助商链接