这个问题涉及两种本质上相同的代码实现。
首先,使用委托创建一个比较方法,该方法可以用作对对象集合进行排序时的参数:
class Foo
{
public static Comparison<Foo> BarComparison = delegate(Foo foo1, Foo foo2)
{
return foo1.Bar.CompareTo(foo2.Bar);
};
}
当我想以不同于我的 CompareTo 函数所提供的方式对一组 Foo 对象进行排序时,我使用上述方法。例如:
List<Foo> fooList = new List<Foo>();
fooList.Sort(BarComparison);
其次,使用 IComparer 接口:
public class BarComparer : IComparer<Foo>
{
public int Compare(Foo foo1, Foo foo2)
{
return foo1.Bar.CompareTo(foo2.Bar);
}
}
当我想在一个Foo对象的集合中进行二分搜索时,我使用上述方法。例如:
BarComparer comparer = new BarComparer();
List<Foo> fooList = new List<Foo>();
Foo foo = new Foo();
int index = fooList.BinarySearch(foo, comparer);
我的问题是:
- 这些实现的优缺点是什么?
- 还有哪些方法可以利用这些实现的优势?
- 是否有一种方式可以将这些实现组合起来,以不需要重复代码的方式进行?
- 我能否只使用其中一种实现来实现二分查找和另一种集合排序的功能?
IComparer<T>
的方法比接受Comparison<T>
更容易测试呢?它们都使用了控制反转。 - AaronaughtIComparer<T>
和Comparison<T>
),不像匿名委托那样难以测试。 - Ron KleinIComparer<T>
本身进行单元测试,而不是接受它的方法。我无法想象实际上想要对其中一个进行单元测试,但你是对的,如果你想要编写测试,那肯定更容易些。 - Aaronaught