我正在寻找一种方法来实现一个集合,该集合可以保证基于DateTime
值的顺序。我最初的想法是使用SortedSet<T1>
这样的自定义IComparer<T1>
:
internal class DateTimeComparer : IComparer<MyType> {
public int Compare(MyType x, MyType y) {
return x.DateTimeProp.CompareTo(y.DateTimeProp);
}
}
var sortedSet = new SortedSet<MyType>(new DateTimeComparer());
然而,这不起作用,因为该集似乎覆盖/替换具有确切时间戳的所有项目。为了验证这个假设,我创建了两个集合,一个是简单列表,在填充后使用DateTime
属性进行排序,另一个基于SortedSet<T1>
- &gt;基于该集合的那个条目缺少几个条目,恰好是具有完全相同时间戳的条目。
有哪些其他选择来实现这样的集合?
答案 0 :(得分:1)
维护已排序的项集合的有效方法是使用二叉搜索树。您当然可以构建自己的二叉搜索树,但是SortedSet<T>
类是使用红黑二叉搜索树实现的,因此重用该类似乎更聪明,这正是您要尝试的。
SortedSet<T>
中项目的排序是通过调用IComparer<T>.Compare
方法比较项目对来控制的。如果此方法返回0,则认为两个项目相等,并且这些项目中只有一个将存储在集合中。对于使用DateTimeComparer
的情况,您会遇到以下问题:只有一个具有特定MyType
的{{1}}实例可以存储在该集合中。
要解决此问题,您必须确保在使用DateTimeProp
方法进行比较时,不同的MyType
实例永远不会相等。您可以修改代码来实现此目的:
DateTimeComparer.Compare
如果两个实例具有不同的class DateTimeComparer : IComparer<MyType> {
readonly ObjectIDGenerator idGenerator = new ObjectIDGenerator();
public int Compare(MyType x, MyType y) {
if (x.DateTimeProp != y.DateTimeProp)
return x.DateTimeProp.CompareTo(y.DateTimeProp);
bool firstTime;
var xId = idGenerator.GetId(x, out firstTime);
var yId = idGenerator.GetId(y, out firstTime);
return xId.CompareTo(yId);
}
}
值,则应根据这些值对它们进行排序。这由最初的DateTimeProp
语句处理。
如果这两个值具有相同的if
值,则需要根据其他一些条件对其进行排序。您可以使用DateTimeProp
的其他属性,但可能存在这些属性相等的情况,除非MyType
和x
引用相同的实例,否则方法永远不会返回0非常重要(例如y
是真的。)
要处理此问题,您可以使用ObjectIDGenerator
,它将为不同的实例分配唯一的64位ID值。然后可以对这些进行比较以提供排序。
请注意,具有相同ReferenceEquals(x, y)
值的项目的排序将是随机但一致的。要控制此排序,您可以使用DateTimeProp
的其他属性,但最终您必须使用生成的ID在两个不同实例的所有属性相同时提供排序。