我想将List.BinarySearch()
与自定义项类型一起使用。自定义类型未实现IComparable<T>
;相反,我调用了几个静态Comparison<T>
函数,因为在不同的点我想按不同的标准对列表进行排序。另外,我认为它增加了清晰度,因为您的排序方式可以通过函数名称来描述。现在我想在列表上进行二进制搜索。我想使用我的一个比较函数,却发现List.BinarySearch()
没有接受Comparison<T>
的重载,只有IComparer<T>
。我试着避免使用IComparer<T>
,因为对于我来说,为了比较对象而有一个单独的类似乎很愚蠢。除了List.BinarySearch()
之外,为什么Comparison<T>
不会超载IComparer<T>
?有没有办法在Comparison<T>
中使用我现有的List.BinarySearch()
函数?
答案 0 :(得分:11)
从IComparer<T>
创建Comparison<T>
非常容易 - 这是MiscUtil中的一个(稍加修改)的课程,欢迎您使用该课程:
/// <summary>
/// Utility to build an IComparer implementation from a Comparison delegate,
/// and a static method to do the reverse.
/// </summary>
public class ComparisonComparer<T> : IComparer<T>
{
private readonly Comparison<T> comparison;
public ComparisonComparer(Comparison<T> comparison)
{
if (comparison == null)
{
throw new ArgumentNullException("comparison");
}
this.comparison = comparison;
}
public int Compare(T x, T y)
{
return comparison(x, y);
}
}
您还可以向List<T>
添加扩展方法,以便为您执行此操作:
public static int BinarySearch<T>(this List<T> list, Comparison<T> comparison)
{
return list.BinarySearch(new ComparisonComparer(comparison));
}
答案 1 :(得分:1)
为Comparison
创建包装器,例如:
public class ComparisonWrapper<T> : IComparer<T>
{
private Comparison<T> comparison;
public ComparisonWrapper(Comparison<T> comparison)
{
this.comparison = comparison;
}
public int Compare(T x, T y)
{
return comparison(x, y);
}
}
答案 2 :(得分:0)
这是Jon的答案的扩展,它采用lambda表达式。
public static class ListExtensions
{
public static int BinarySearch<T>(this List<T> list, T item, Func<T, T, int> compare)
{
return list.BinarySearch(item, new ComparisonComparer<T>(compare));
}
}
public class ComparisonComparer<T> : IComparer<T>
{
private readonly Comparison<T> comparison;
public ComparisonComparer(Func<T, T, int> compare)
{
if (compare == null)
{
throw new ArgumentNullException("comparison");
}
comparison = new Comparison<T>(compare);
}
public int Compare(T x, T y)
{
return comparison(x, y);
}
}