为什么List.BinarySearch()除了IComparer <t>之外还有比较<t>的重载?</t> </t>

时间:2011-12-06 19:43:58

标签: c# .net comparison binary-search icomparer

我想将List.BinarySearch()与自定义项类型一起使用。自定义类型未实现IComparable<T>;相反,我调用了几个静态Comparison<T>函数,因为在不同的点我想按不同的标准对列表进行排序。另外,我认为它增加了清晰度,因为您的排序方式可以通过函数名称来描述。现在我想在列表上进行二进制搜索。我想使用我的一个比较函数,却发现List.BinarySearch()没有接受Comparison<T>的重载,只有IComparer<T>。我试着避免使用IComparer<T>,因为对于我来说,为了比较对象而有一个单独的类似乎很愚蠢。除了List.BinarySearch()之外,为什么Comparison<T>不会超载IComparer<T>?有没有办法在Comparison<T>中使用我现有的List.BinarySearch()函数?

3 个答案:

答案 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);
    }
}