Effective C# 原则26:用IComparable和IComparer实现对象的顺序关系
2009-02-19 08:16:22 来源:WEB开发网所有客户的顺序关系就是这样:以名字排序。不久,你很可能要创建一个报表,要以客户的收入进行排序。你还是需要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 可以为排序提供一个可选的排序依据,这可以用于一些没有给你提供排序依据的类型上,提供你自己的排序依据。
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# 原则系列文章目录
更多精彩
赞助商链接