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

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

 2009-02-19 08:16:22 来源:WEB开发网   
核心提示: 所有客户的顺序关系就是这样:以名字排序,不久,Effective C# 原则26:用IComparable和IComparer实现对象的顺序关系(4),你很可能要创建一个报表,要以客户的收入进行排序,IComparer 可以为排序提供一个可选的排序依据,这可以用于一些没有给你提供排序依据的

所有客户的顺序关系就是这样:以名字排序。不久,你很可能要创建一个报表,要以客户的收入进行排序。你还是需要Custom结构里定义的普通的比较机制:以名字排序。你可以通过添加一个实现了IComparer 接口的类来完成这个新增的需求。IComparer给类型比较提供另一个标准的选择,在.Net FCL中任何在IComparable接口上工作的函数,都提供一个重载,以便通过接口对对象进行排序。因为你是Customer结构的作者,你可以创建一个新的类(RevenueComparer)做为Customer结构的一个私有的嵌套类。它通过Customer结构的静态属性暴露给用户:

public struct Customer : IComparable
{
 private string _name;
 private double _revenue;
 // code from earlier example elided.
 private static RevenueComparer _revComp = null;
 // return an object that implements IComparer
 // use lazy evaluation to create just one.
 public static IComparer RevenueCompare
 {
  get
  {
   if ( _revComp == null )
    _revComp = new RevenueComparer();
   return _revComp;
  }
 }
 // Class to compare customers by revenue.
 // This is always used via the interface pointer,
 // so only provide the interface override.
 private class RevenueComparer : IComparer
 {
  #region IComparer Members
  int IComparer.Compare( object left, object right )
  {
   if ( ! ( left is Customer ) )
    throw new ArgumentException(
     "Argument is not a Customer",
     "left");
   if (! ( right is Customer) )
    throw new ArgumentException(
     "Argument is not a Customer",
     "right");
   Customer leftCustomer = ( Customer ) left;
   Customer rightCustomer = ( Customer ) right;
   return leftCustomer._revenue.CompareTo(
    rightCustomer._revenue);
  }
  #endregion
 }
}

最后这个版本的Customer结构,包含了RevenueComparer类,这样你就可以以自然顺序-名字,对对象进行排序;还可有一个选择就是用这个暴露出来的,实现了IComparer 接口的类,以收入对客户进行排序。如果你没有办法访问Customer类的源代码,你还可以提供一个IComparer接口,用于对它的任何公共属性进行排序。只有在你无法取得源代码时才使用这样的习惯,同时也是在.Net框架里的一个类须要不同的排序依据时才这样用。

这一原则里没有涉及Equals()方法和==操作符(参见原则9)。排序和相等是很清楚的操作,你不用实现一个相等比较来表达排序关系。 实际上,引用类型通常是基于对象的内容进行排序的,而相等则是基于对象的ID的。在Equals()返回false时,CompareTo()可以返回0。这完全是合法的,相等与排序完全没必要一样。

(译注:注意作者这里讨论的对象,是排序与相等这两种操作,而不是具体的对象,对于一些特殊的对象,相等与排序可能相关。)

IComparable 和IComparer接口为类型的排序提供了标准的机制,IComparable 应该在大多数自然排序下使用。当你实现IComparable接口时,你应该为类型排序重载一致的比较操作符(<, >, <=, >=)。IComparable.CompareTo()使用的是System.Object做为参数,同样你也要重载一个类型安全的CompareTo()方法。IComparer 可以为排序提供一个可选的排序依据,这可以用于一些没有给你提供排序依据的类型上,提供你自己的排序依据。

上一页  1 2 3 4 

Tags:Effective 原则 IComparable

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