Почему List.BinarySearch () не имеет перегрузок, которые сравнивают <T>с IComparer <T>? - PullRequest
5 голосов
/ 06 декабря 2011

Я хочу использовать 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 ]

11 голосов
/ 06 декабря 2011

Очень просто создать 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 голос
/ 06 декабря 2011

Создать упаковку для 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);
    }
}
0 голосов
/ 19 января 2013

Вот расширение ответа Джона, которое принимает лямбда-выражение.

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);
    }
}
...