維護項目排序集合的有效方法是使用二叉搜索樹。您當然可以構建自己的二叉搜索樹,但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'時,如果兩個值具有相同的時間戳,則認爲它們是相同的,因此即使在考慮其他屬性時值不同,您也只能爲特定時間戳存儲單個值。 –