【问题标题】:How to effectively replicate ArrayList.BinarySearch in List<T>.BinarySearch?如何在 List<T>.BinarySearch 中有效地复制 ArrayList.BinarySearch?
【发布时间】:2013-03-24 20:58:16
【问题描述】:

我正在尝试将旧项目从使用 ArrayList 集合升级到 List。一切都很顺利,除了转换 ArrayList.BinarySearch。虽然 List 有一个相应的方法,但 ArrayList.BinarySearch 有一个接受 arbitrary object 的重载,而 List.BinarySearch 需要一个 object of type T。下面的例子。

我怎样才能有效地用 List 替换这个 ArrayList 功能?还是我必须自己动手?

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

【问题讨论】:

  • 如果你有一个List&lt;T&gt;,为什么要传入一个不是T 类型的对象?这样的对象不能在列表中。
  • 只需为可以接受任意对象的 List 编写自己的 BinarySearch 扩展方法,这应该很容易。
  • @Dmitry Osinovskiy 有一个不错的想法(进行扩展)。就我个人而言,我尽量避免使用扩展方法。我认为您应该投入更多时间来重构代码并将 BinarySearch 与通用比较器一起使用。
  • @AdamRobinson 如果 Comparer 对象支持,您可以传入它。搜索基于对象中的参数以外的参数。代码不是最容易理解的,它是由一个喜欢从所有东西中抽象出活生生的废话的人编写的,以至于没有人能真正理解发生了什么。因此,一个外来对象被传递到 BinarySearch 方法中。
  • @AngryHacker 只需从 en.wikibooks.org/wiki/Algorithm_Implementation/Search/… 获取代码并将 int[] 更改为 List,将 int 更改为对象,将 IComparer 添加为单独的参数,将 == 和

标签: c# generics arraylist binary-search


【解决方案1】:

要使用ArrayList.BinarySearch 使用的相同方法,请将List&lt;T&gt; 转换为数组并调用Array.BinarySearch(Array, object)。不幸的是,您需要转换/复制到新数组。

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

我确实质疑你的方法,因为 List&lt;T&gt; 是强类型的,它只会包含类型 T。如果您出于某种原因不确定该类型是否属于列表中的类型,请事先检查或制作一个扩展方法来为您完成。

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

【讨论】:

    猜你喜欢
    • 2011-06-23
    • 2011-03-16
    • 1970-01-01
    • 1970-01-01
    • 2011-02-03
    • 1970-01-01
    • 1970-01-01
    • 2021-07-12
    • 2016-09-28
    相关资源
    最近更新 更多