Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to effectively replicate ArrayList.BinarySearch in List<T>.BinarySearch?

I am trying to upgrade an old project from using ArrayList collections to List. Everything went pretty smooth, except for converting ArrayList.BinarySearch. While List has a corresponding method, the ArrayList.BinarySearch has an overload that accepts an arbitrary object while List.BinarySearch demands an object of type T. Example below.

How can I effectively replace this ArrayList functionality with List? Or do I have to roll my own?

class Pod {
   public DateTime Start { get; set; }
}

class TimeRange: IComparer {
    TimeSpan StartsAt { get; set; }
    ITimeRangeComparer TimeComparer { get; set; }
    public int Compare(object x, object y) {
       // there is more to it, but basically compares time ranges
       return comparer.Compare((TimeRange) x, (TimeRange) y);
    }        
}

class Manager {
   void DoStuff() {
        ArrayList alPods = GetPodsAL();
        List<Pod> lstPods = GetPodsLST();
        int stopIndex;

        TimeRange startPoint = GetStartPoint();
        TimeRange stopPoint = GetStopPoint();

        // ArrayList works fine
        stopIndex = alPods.BinarySearch(stopPoint, startPoint.TimeComparer);

        // Fails because the method demands that `stopPoint` be of type Pod
        stopIndex = lstPods.BinarySearch(stopPoint, startPoint.TimeComparer);
   }
}
like image 528
AngryHacker Avatar asked Jun 10 '26 01:06

AngryHacker


1 Answers

To use the same method that ArrayList.BinarySearch uses, convert your List<T> to an array and call Array.BinarySearch(Array, object). Unfortunately you would need to do a conversion/copy to a new array.

List<SomeType> list;
SomeType value;
// ...
Array.BinarySearch(list.ToArray(), value)

I do question your approach though, being as a List<T> is strongly-typed, it will only ever contain the type T. If you're unsure for some reason whether the type would be of that in the list then check before-hand or make an extension method to do it for you.

public static class ListExtensionMethods
{
    public static int BinarySearch<T>(this List<T> list, object value)
    {
        if (value is T)
            return list.BinarySearch((T)value);
        return -1;
    }
}
like image 155
Daniel Imms Avatar answered Jun 11 '26 15:06

Daniel Imms