基于DateTime

时间:2016-12-15 22:32:25

标签: c# .net datetime collections

我正在寻找一种方法来实现一个集合,该集合可以保证基于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;基于该集合的那个条目缺少几个条目,恰好是具有完全相同时间戳的条目。

有哪些其他选择来实现这样的集合?

1 个答案:

答案 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的其他属性,但可能存在这些属性相等的情况,除非MyTypex引用相同的实例,否则方法永远不会返回0非常重要(例如y是真的。)

要处理此问题,您可以使用ObjectIDGenerator,它将为不同的实例分配唯一的64位ID值。然后可以对这些进行比较以提供排序。

请注意,具有相同ReferenceEquals(x, y)值的项目的排序将是随机但一致的。要控制此排序,您可以使用DateTimeProp的其他属性,但最终您必须使用生成的ID在两个不同实例的所有属性相同时提供排序。