Waarom heeft List.BinarySearch () geen overbelastingen die <T> naast IComparer <T> gebruiken?

I want to use List.BinarySearch() with a custom item type. The custom type does not implement IComparable; instead I have several static Comparison functions that I call because at various points I want to sort the list on different criteria. Plus I think it adds clarity since the way you are sorting can be described by the function name. Now I want to do a binary search on the list. I wanted to use one of my comparison functions, only to find that List.BinarySearch() doesn't have an overload that accepts Comparison, only IComparer. I try to avoid IComparer because it seems silly to me to have a separate class just for comparing objects. Why doesn't List.BinarySearch() have overloads that take Comparison in addition to IComparer? And is there any way to use my existing Comparison functions in List.BinarySearch()?

5
Het is een omissie, we moeten de bug aan Microsoft melden.
toegevoegd de auteur Colonel Panic, de bron
toegevoegd de auteur Colonel Panic, de bron
Maak een vergelijker die delegeert naar uw vergelijking. Klaar om te vertrekken.
toegevoegd de auteur Anthony Pegram, de bron
waar is de code die u gebruikt om de zoekopdracht te doen, een foreach of voor lus .. ??
toegevoegd de auteur MethodMan, de bron
Kan iemand mijn eerste vraag beantwoorden: waarom heeft List.BinarySearch() geen overloads die Vergelijk gebruiken naast IComparer ? Gewoon uit nieuwsgierigheid...
toegevoegd de auteur Craig W, de bron

3 antwoord

It's very easy to create an IComparer from a Comparison - here's a (slightly amended) class from MiscUtil which you're welcome to use:

/// 
/// Utility to build an IComparer implementation from a Comparison delegate,
/// and a static method to do the reverse.
/// 
public class ComparisonComparer : IComparer
{
    private readonly Comparison comparison;

    public ComparisonComparer(Comparison comparison)
    {
        if (comparison == null)
        {
            throw new ArgumentNullException("comparison");
        }
        this.comparison = comparison;
    }

    public int Compare(T x, T y)
    {
        return comparison(x, y);
    }
}

You could also add an extension method to List to do this for you:

public static int BinarySearch(this List list, Comparison comparison)
{
    return list.BinarySearch(new ComparisonComparer(comparison));
}
11
toegevoegd
@ JonSkeet: ik zie niet in waarom dat zou zijn, omdat er een equivalente overbelasting is voor .Sort() die Vergelijking gebruikt. Ik denk dat ze het gewoon over het hoofd hebben gezien.
toegevoegd de auteur BlueRaja - Danny Pflughoeft, de bron
@Craig: zoals altijd zijn er kosten verbonden aan het introduceren van iets. Ik vermoed dat de BCL-beheerders van mening zijn dat het niet echt de lat van nut is ten koste van de kosten.
toegevoegd de auteur Jon Skeet, de bron
@ BlueRaja-DannyPflughoeft: Het is misschien niet dezelfde persoon die de beslissing heeft genomen voor beide methoden, natuurlijk.
toegevoegd de auteur Jon Skeet, de bron
Ik denk dat dit de beste oplossing is, hoewel ik er niet zo dol op ben. Ik ben nog steeds erg benieuwd waarom de overbelastingen niet bestaan ​​om Vergelijking rechtstreeks te gebruiken.
toegevoegd de auteur Craig W, de bron

Maak een wrapper voor vergelijking zoals deze:

public class ComparisonWrapper : IComparer
{
    private Comparison comparison;
    public ComparisonWrapper(Comparison comparison)
    {
        this.comparison = comparison;
    }

    public int Compare(T x, T y)
    {
        return comparison(x, y);
    }
}
1
toegevoegd

Hier is een uitbreiding op het antwoord van Jon dat een lambda-uitdrukking aanneemt.

public static class ListExtensions
{
    public static int BinarySearch(this List list, T item, Func compare)
    {
        return list.BinarySearch(item, new ComparisonComparer(compare));
    }
}

public class ComparisonComparer : IComparer
{
    private readonly Comparison comparison;

    public ComparisonComparer(Func compare)
    {
        if (compare == null)
        {
            throw new ArgumentNullException("comparison");
        }
        comparison = new Comparison(compare);
    }

    public int Compare(T x, T y)
    {
        return comparison(x, y);
    }
}
0
toegevoegd