【发布时间】: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<T>,为什么要传入一个不是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