2017-05-09 87 views
0

在閱讀有關在SortedList中使用Linq時期望的文檔後,我感到困惑。SortedList和Linq

https://msdn.microsoft.com/en-us/library/ms132319(v=vs.110).aspx

我猜枚舉保證排序並且還通過指數檢索,但對於值和鍵?所有這些情況都安全嗎?

 var list = new SortedList<DateTime, object>(); 

     //add entries here ... 

     var firstValue1 = list.Values[0]; 
     var firstValue2 = list.First().Value; 
     var firstValue3 = list.Values.First(); 

     var firstKey1 = list.Keys[list.Count-1]; 
     var firstKey2 = list.First().Key; 
     var firstKey3 = list.Keys.First(); 

     var sortedList = list.Where(x => x.Key > DateTime.Now) 
      .Select(x => x.Value); 
+0

Linq查詢的重點是實際上查詢某些東西,所以只需要'.First().Value'就像隨機給我一樣。 – EpicKip

+0

@EpicKip:我沒有關注。什麼使得隨機而不是獲得排序列表中的第一個項目? – Chris

+0

SortedList對象的元素根據創建SortedList時指定的特定IComparer實現或根據密鑰本身提供的IComparable實現按鍵排序。 – Equalsk

回答

0

您可以檢查出的源代碼在這裏:

https://referencesource.microsoft.com/#System/compmod/system/collections/generic/sortedlist.cs,de670561692e4a20

顯然,Keys屬性就在這個類的一個實例的包裝:

https://referencesource.microsoft.com/#System/compmod/system/collections/generic/sortedlist.cs,374aa21b960ae2e2

如果你看看GetEnumerator()方法,你可以看到它創建了一個SortedListKeyEnumerator。下面是該代碼:

https://referencesource.microsoft.com/#System/compmod/system/collections/generic/sortedlist.cs,a4492235f85c77d8

據我所知,這只是迭代通過包含SortedList的鍵MoveNext()

你可以找到Values如何工作的相同方式。

+0

源代碼可以更改,記錄的保證不會。 :) – Stig

+0

@Stig文檔保證也會更改,只是更少。 C#和.NET確實在之前做出了突破性的改變,儘管很少。 – Servy

0

如果您查看Enumerable.cs的源代碼,您將看到沒有謂詞的重載只是試圖將源視爲IList,如果不起作用,它將使用枚舉器返回第一個元素。無論是指數和普查員都應該是讓你得到適當的(排序)結果由排序列表類的內部處理:

public static TSource First<TSource>(this IEnumerable<TSource> source) { 
      if (source == null) throw Error.ArgumentNull("source"); 
      IList<TSource> list = source as IList<TSource>; 
      if (list != null) { 
       if (list.Count > 0) return list[0]; 
      } 
      else { 
       using (IEnumerator<TSource> e = source.GetEnumerator()) { 
        if (e.MoveNext()) return e.Current; 
       } 
      } 
      throw Error.NoElements(); 
     } 

與謂詞超載工作方式略有不同,它針對每一個執行謂詞使用項目枚舉,尋找第一場比賽:

public static TSource First<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate) { 
     if (source == null) throw Error.ArgumentNull("source"); 
     if (predicate == null) throw Error.ArgumentNull("predicate"); 
     foreach (TSource element in source) { 
      if (predicate(element)) return element; 
     } 
     throw Error.NoMatch(); 
    } 

無論哪種方式,你應該得到相同的(排序)結果。