我有一个基类Event
,其DateTime
成员TimeStamp
。
许多其他事件类将源于此。
我希望能够快速搜索事件列表,所以我想使用二进制搜索。
(列表数据按时间戳排序,但同时发生的事件可能存在重复的时间戳)
所以我开始写这样的东西:
public class EventList<T> : List<T> where T : Event
{
private IComparer<T> comparer = (x, y) => Comparer<DateTime>.Default.Compare(x.TimeStamp, y.TimeStamp);
public IEnumerable<T> EventsBetween(DateTime inFromTime, DateTime inToTime)
{
// Find the index for the beginning.
int index = this.BinarySearch(inFromTime, comparer);
// BLAH REST OF IMPLEMENTATION
}
}
问题是BinarySearch只接受T(所以 - Event
类型)作为参数,而我想基于T的成员进行搜索 - TimeStamp
什么是接近这个的好方法?
答案 0 :(得分:1)
我认为您已经使用comparer
功能正确的方式。它通过比较它们的日期来比较两个T。
要处理inFromTime
BinarySearch
参数,您可以创建一个具有正确TimeStamp
的虚拟事件,并将该虚拟传递给BinarySearch
。
另外,只是为了确保:列表是否按时间字段排序?否则binarysearch将无效。
这个问题比我想象的要复杂得多。可以帮助您的解决方案是:
不幸的是没有内置BinarySearch extension method,所以你必须自己编写。如果您编写自己的搜索,将其放入扩展方法可能不值得花费额外的努力。在这种情况下,只需在EventList类中自己实现自定义BinarySearch算法,就可以做到最好。
另一种选择是,如果有一种形式的BinarySearch接受了一个从T中提取相关密钥的代理,但是也没有。
答案 1 :(得分:0)
最简单的方法是定义一个实现IComparer<T>
的小助手类。
public class CompUtil : IComparer<T> {
public int Compare(T left, T right) {
return left.TimeStamp.CompareTo(right.TimeStamp);
}
}
然后您可以按如下方式使用它
int index = this.BinarySearch(inFromTime, new CompUtil());
答案 2 :(得分:0)
如果您的Event
类包含要排序的属性,那么您的方法就可以了。然后,编译器可以验证传入的T是什么,它将继承自Event并包含DateTime属性。如果Event
不包含DateTime属性,您可能希望将其添加到事件,或将T约束为更具体的类型,其中包含搜索所需的属性。
请务必确保在应用BinarySearch之前对列表进行排序。
答案 3 :(得分:0)
public class EventList<TEvent, TData>
: List<TEvent> where TEvent : Event, TData: DataTime
{
class Comparer : IComparer<TData> { } // as JaredPar mentioned above
public IEnumerable<TEvent> EventsBetween(TData from, TData to) { }
}
答案 4 :(得分:0)
也许您可以考虑使用SortedList作为基类而不是List。然后,您可以使用IndexOfKey方法搜索指定的TimeStamp。该方法进行二分查找。