维护项目排序集合的有效方法是使用二叉搜索树。您当然可以构建自己的二叉搜索树,但SortedSet<T>
类是使用红黑二叉搜索树实现的,因此重用该类正是您正在尝试执行的操作似乎更智能。
SortedSet<T>
中物品的排序通过调用IComparer<T>.Compare
方法比较物品对来控制。如果此方法返回0,则两个项目被视为相等,并且只有其中一个项目将存储在该集合中。在DateTimeComparer
的情况下,您会遇到这样的问题,只有一个具有指定DateTimeProp
的MyType
实例可以存储在该集合中。
要解决此问题,必须确保使用DateTimeComparer.Compare
方法进行比较时,不同的MyType
实例永远不会相等。您可以通过修改代码来实现这一目标:
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
和y
引用相同的实例(例如ReferenceEquals(x, y)
为true),否则该方法从不返回0是很重要的。
要处理这个问题,您可以使用ObjectIDGenerator
,它将为不同的实例分配唯一的64位ID值。这些可以进行比较以提供订购。
请注意,具有相同DateTimeProp
值的项目排序将是随机的但一致。要控制这种排序,您可以使用MyType
的其他属性,但最终,如果两个不同实例的所有属性都相同,则必须使用生成的ID来提供排序。
任何你不想把所有东西都添加到列表中然后对其进行排序的原因? –
你尝试过'SortedList'吗? (请注意,排序列表比正常列表慢,因为每次访问具有索引的项目时,它都执行二进制搜索,而列表将直接为您提供该索引内的项目) –
一个集合只能包含特定值一次。使用'DateTimeComparer'时,如果两个值具有相同的时间戳,则认为它们是相同的,因此即使在考虑其他属性时值不同,您也只能为特定时间戳存储单个值。 –