Search code examples
c#.netcomparisonbinary-searchicomparer

Why doesn't List.BinarySearch() have overloads that take Comparison<T> in addition to IComparer<T>?


I want to use List.BinarySearch() with a custom item type. The custom type does not implement IComparable<T>; instead I have several static Comparison<T> 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<T>, only IComparer<T>. I try to avoid IComparer<T> 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<T> in addition to IComparer<T>? And is there any way to use my existing Comparison<T> functions in List.BinarySearch()?


Solution

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

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

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

    public static int BinarySearch<T>(this List<T> list, Comparison<T> comparison)
    {
        return list.BinarySearch(new ComparisonComparer(comparison));
    }