虽然在.Net类库里有System.Collections.Generic.Comparer<>这个基础比较器,但是我用起来觉得不爽.因为如果是自定义类型还要继承并实现IComparer<>接口实现一个特定的比较器太麻烦了,再者我不喜欢动不动就继承接口这种理论的面向对象编程方式.所以就自己写个Comparer看着舒心用着踏实.
自己写比较器只要能实现两个功能就行,1能支持基础类型,2能够方便扩展自定义类型.基于此我使用委托(System.Comparison<>).实现思路很简单在类里使用一个Dictionary来保存类型和Delegate的键值对.在类的静态构造里初始化基础类型的Comparison,自定义类型通过由用户实现并添加到Dictionary中.
为什么要用Delegate来做值呢?因为Comparison<int>,Comparison<double>是不同的类型所以只能使用委托的基类Delegate来代替这些具体类型(Array,Enum同理).在使用的时候只要转下类型就ok了,这个没有什么性能损失.这个比较器还要使用单例模式这样就完美了.
代码:
public class BComparer<T>
{
Comparison<T> _comparison; //比较委托
static readonly Dictionary<Type, Delegate> _map = new Dictionary<Type, Delegate>();
//实现单例
static readonly BComparer<T> _instance = new BComparer<T>();
private BComparer() {}
public static BComparer<T> Instance
{
get
{
System.Diagnostics.Debug.Assert(_map.ContainsKey(typeof(T)));
//强转为具体的比较委托
_instance._comparison = (Comparison<T>)_map[typeof(T)];
return _instance;
}
}
//情态构造,初始化
static BComparer()
{
//基础类型比较器
Type t = typeof(T);
if (t == typeof(bool))
{
Comparison<bool> cmp_bool = delegate(bool t1, bool t2)
{ return t1 == t2 ? 0 : (t1 ? 1 : -1); };
_map.Add(typeof(bool), (Delegate)cmp_bool);
}
if (t == typeof(int))
{
Comparison<int> cmp_int = delegate(int t1, int t2)
{ return t1 > t2 ? 1 : (t1 == t2 ? 0 : -1); };
_map.Add(typeof(int), (Delegate)cmp_int);
}
//....其他
}
//注册自定义比较
public static void Register<NT>(Comparison<NT> comparison)
{
System.Diagnostics.Debug.Assert(_map.ContainsKey(typeof(NT)) == false);
_map.Add(typeof(NT), (Delegate)comparison);
}
//比较函数,以后用来实现IComparer用
public int Compare(T t1, T t2)
{
System.Diagnostics.Debug.Assert(_comparison != null);
return _comparison(t1, t2);
}
自己写比较器只要能实现两个功能就行,1能支持基础类型,2能够方便扩展自定义类型.基于此我使用委托(System.Comparison<>).实现思路很简单在类里使用一个Dictionary来保存类型和Delegate的键值对.在类的静态构造里初始化基础类型的Comparison,自定义类型通过由用户实现并添加到Dictionary中.
为什么要用Delegate来做值呢?因为Comparison<int>,Comparison<double>是不同的类型所以只能使用委托的基类Delegate来代替这些具体类型(Array,Enum同理).在使用的时候只要转下类型就ok了,这个没有什么性能损失.这个比较器还要使用单例模式这样就完美了.
代码:
public class BComparer<T>
{
Comparison<T> _comparison; //比较委托
static readonly Dictionary<Type, Delegate> _map = new Dictionary<Type, Delegate>();
//实现单例
static readonly BComparer<T> _instance = new BComparer<T>();
private BComparer() {}
public static BComparer<T> Instance
{
get
{
System.Diagnostics.Debug.Assert(_map.ContainsKey(typeof(T)));
//强转为具体的比较委托
_instance._comparison = (Comparison<T>)_map[typeof(T)];
return _instance;
}
}
//情态构造,初始化
static BComparer()
{
//基础类型比较器
Type t = typeof(T);
if (t == typeof(bool))
{
Comparison<bool> cmp_bool = delegate(bool t1, bool t2)
{ return t1 == t2 ? 0 : (t1 ? 1 : -1); };
_map.Add(typeof(bool), (Delegate)cmp_bool);
}
if (t == typeof(int))
{
Comparison<int> cmp_int = delegate(int t1, int t2)
{ return t1 > t2 ? 1 : (t1 == t2 ? 0 : -1); };
_map.Add(typeof(int), (Delegate)cmp_int);
}
//....其他
}
//注册自定义比较
public static void Register<NT>(Comparison<NT> comparison)
{
System.Diagnostics.Debug.Assert(_map.ContainsKey(typeof(NT)) == false);
_map.Add(typeof(NT), (Delegate)comparison);
}
//比较函数,以后用来实现IComparer用
public int Compare(T t1, T t2)
{
System.Diagnostics.Debug.Assert(_comparison != null);
return _comparison(t1, t2);
}