Effective C# 学习笔记(三十一)利用IComparable<T>和IComparer<T>接口来实现排序关系
2011-07-17 21:13
706 查看
你的类型需通过描述在集合中该类型的对象该如何排序和被查找来说明其排序关系。
.NET framework中定义了IComaprable<T>和IComparer<T>接口来为你的类型定义排序关系。
前者定义了你类型的自然排序方式,后者则定义了其他的排序方式(通过<,>,<=,>=等运算关系的定义来提高在运行时的比较性能)。
IComparable<T>接口包含一个CompareTo()方法(该方法的时间复杂度平均为n
lg(n)),该方法返回0时该对象和比较对象相等,返回小于0的值时则该对象小于比较对象,返回大于0值时该对象大于比较对象。而为了和一些旧的APIs相兼容,你需要同时实现IComparable非范型比较接口,该接口的CompareTo接受Object对象类型参数,所以你要对类型进行转换检查。下面的代码是一个简单的实现:
public struct
Customer : IComparable<Customer>, IComparable
{
private
readonly string name;
public
Customer(string name)
{
this.name
= name;
}
#region
IComparable<Customer> Members
public
int CompareTo(Customer other)
{
return
name.CompareTo(other.name);
}
#endregion
#region
IComparable Members
int
IComparable.CompareTo(object obj)
{
if
(!(obj is Customer))
throw
new ArgumentException(
"Argument
is not a Customer", "obj");
Customer
otherCustomer = (Customer)obj;
return
this.CompareTo(otherCustomer);
}
#endregion
}
出了实现Icomparable<T>和IComparable接口外,你还可以定义比较运算符来给客户端提供更方便的比较方式,代码如下:
public struct
Customer : IComparable<Customer>, IComparable
{
private
readonly string name;
public
Customer(string name)
{
this.name
= name;
}
#region
IComparable<Customer> Members
public
int CompareTo(Customer other)
{
return
name.CompareTo(other.name);
}
#endregion
#region
IComparable Members
int
IComparable.CompareTo(object obj)
{
if
(!(obj is Customer))
throw
new ArgumentException(
"Argument
is not a Customer", "obj");
Customer
otherCustomer = (Customer)obj;
return
this.CompareTo(otherCustomer);
}
#endregion
//
Relational Operators.
public
static bool operator <(Customer left,Customer right)
{
return
left.CompareTo(right) < 0;
}
public
static bool operator <=(Customer left,Customer right)
{
return
left.CompareTo(right) <= 0;
}
public
static bool operator >(Customer left,Customer right)
{
return
left.CompareTo(right) > 0;
}
public
static bool operator >=(Customer left,Customer right)
{
return
left.CompareTo(right) >= 0;
}
}
通过创建静态属性来提供非标准的排序支持定义,代码如下:
public static
Comparison<Customer> CompareByReview
{
get
{
return
(left,right) => left.revenue.CompareTo(right.revenue);
}
}
而一些旧的类库需要通过实现IComparer接口的功能,来提供非标准的排序定义。注意:这种通过创建辅助排序类来定义排序的方式建议只在你没有权限访问到原有类型的源码时使用。代码如下:
//1. 先定义一个继承自IComparer<T>接口的类型:
// Class to compare
customers by revenue.
// This is always
used via the interface pointer,
// so only provide
the interface override.
private class
RevenueComparer : IComparer<Customer>
{
#region
IComparer<Customer> Members
int
IComparer<Customer>.Compare(Customer left,Customer right)
{
return
left.revenue.CompareTo(
right.revenue);
}
#endregion
}
//2. 定义该类型的静态属性,单例形式创建
private static
RevenueComparer revComp = null;
// return an object
that implements IComparer
// use lazy
evaluation to create just one.
public static
IComparer<Customer> RevenueCompare
{
get
{
if
(revComp == null)
revComp
= new RevenueComparer();
return
revComp;
}
}
.NET framework中定义了IComaprable<T>和IComparer<T>接口来为你的类型定义排序关系。
前者定义了你类型的自然排序方式,后者则定义了其他的排序方式(通过<,>,<=,>=等运算关系的定义来提高在运行时的比较性能)。
IComparable<T>接口包含一个CompareTo()方法(该方法的时间复杂度平均为n
lg(n)),该方法返回0时该对象和比较对象相等,返回小于0的值时则该对象小于比较对象,返回大于0值时该对象大于比较对象。而为了和一些旧的APIs相兼容,你需要同时实现IComparable非范型比较接口,该接口的CompareTo接受Object对象类型参数,所以你要对类型进行转换检查。下面的代码是一个简单的实现:
public struct
Customer : IComparable<Customer>, IComparable
{
private
readonly string name;
public
Customer(string name)
{
this.name
= name;
}
#region
IComparable<Customer> Members
public
int CompareTo(Customer other)
{
return
name.CompareTo(other.name);
}
#endregion
#region
IComparable Members
int
IComparable.CompareTo(object obj)
{
if
(!(obj is Customer))
throw
new ArgumentException(
"Argument
is not a Customer", "obj");
Customer
otherCustomer = (Customer)obj;
return
this.CompareTo(otherCustomer);
}
#endregion
}
出了实现Icomparable<T>和IComparable接口外,你还可以定义比较运算符来给客户端提供更方便的比较方式,代码如下:
public struct
Customer : IComparable<Customer>, IComparable
{
private
readonly string name;
public
Customer(string name)
{
this.name
= name;
}
#region
IComparable<Customer> Members
public
int CompareTo(Customer other)
{
return
name.CompareTo(other.name);
}
#endregion
#region
IComparable Members
int
IComparable.CompareTo(object obj)
{
if
(!(obj is Customer))
throw
new ArgumentException(
"Argument
is not a Customer", "obj");
Customer
otherCustomer = (Customer)obj;
return
this.CompareTo(otherCustomer);
}
#endregion
//
Relational Operators.
public
static bool operator <(Customer left,Customer right)
{
return
left.CompareTo(right) < 0;
}
public
static bool operator <=(Customer left,Customer right)
{
return
left.CompareTo(right) <= 0;
}
public
static bool operator >(Customer left,Customer right)
{
return
left.CompareTo(right) > 0;
}
public
static bool operator >=(Customer left,Customer right)
{
return
left.CompareTo(right) >= 0;
}
}
通过创建静态属性来提供非标准的排序支持定义,代码如下:
public static
Comparison<Customer> CompareByReview
{
get
{
return
(left,right) => left.revenue.CompareTo(right.revenue);
}
}
而一些旧的类库需要通过实现IComparer接口的功能,来提供非标准的排序定义。注意:这种通过创建辅助排序类来定义排序的方式建议只在你没有权限访问到原有类型的源码时使用。代码如下:
//1. 先定义一个继承自IComparer<T>接口的类型:
// Class to compare
customers by revenue.
// This is always
used via the interface pointer,
// so only provide
the interface override.
private class
RevenueComparer : IComparer<Customer>
{
#region
IComparer<Customer> Members
int
IComparer<Customer>.Compare(Customer left,Customer right)
{
return
left.revenue.CompareTo(
right.revenue);
}
#endregion
}
//2. 定义该类型的静态属性,单例形式创建
private static
RevenueComparer revComp = null;
// return an object
that implements IComparer
// use lazy
evaluation to create just one.
public static
IComparer<Customer> RevenueCompare
{
get
{
if
(revComp == null)
revComp
= new RevenueComparer();
return
revComp;
}
}
相关文章推荐
- 对象的比较与排序(三):实现IComparable<T>和IComparer<T>泛型接口(转)
- 对象的比较与排序(三):实现IComparable<T>和IComparer<T>泛型接口
- 学习java笔记 --- 一个实现Iterable<E>接口的小范例
- 对象的比较与排序(三):实现IComparable<T>和IComparer<T>泛型接口
- C#学习笔记 IEquatable<T> 接口 IEqualityComparer<T> 接口
- C#学习笔记 IComparable接口 IComparable<T>接口 IComparer接口
- Effective C# 使用IComparable和IComparer接口实现排序关系
- Effective C# 使用IComparable和IComparer接口实现排序关系
- Effective C# 学习笔记(四十一)使利用DynamicObject或IDynamicMetaObjectProvider接口实现数据驱动的动态类型
- 我的Java开发学习之旅------>Java利用Comparator接口对多个排序条件进行处理
- C#中IComparable<T>和IComparer<T>接口的使用
- java实现万年历<51cto学院学习笔记>
- C#之IComparable用法,实现List<T>.sort()排序
- 《Effective C#》读书笔记——条目22:通过定义并实现接口替代继承<使用C#表达设计>
- List<>根据指定属性排序(实现IComparer接口)
- Java学习笔记<1>(抽象类和接口)
- C# List<> 实现 IComparer 接口 排序
- Java学习笔记——利用接口和observer实现对象监视
- 笔记(显示实现接口,实现IComparable,IComparer接口来排序)
- C#中的delegate以及利用List<T>中delegate快速实现排序、查找