WEB开发网
开发学院软件开发C语言 Effective C# 原则26:用IComparable和IComparer实... 阅读

Effective C# 原则26:用IComparable和IComparer实现对象的顺序关系

 2009-02-19 08:16:22 来源:WEB开发网   
核心提示:你的类型应该有一个顺序关系,以便在集合中描述它们如何存储以及排序,Effective C# 原则26:用IComparable和IComparer实现对象的顺序关系,.Net框架为你提供了两个接口来描述对象的顺序关系:IComparable 和IComparer,IComparable 为你的类定义了自然顺序,你无法改

你的类型应该有一个顺序关系,以便在集合中描述它们如何存储以及排序。.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 对象操作:

1 2 3 4  下一页

Tags:Effective 原则 IComparable

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接