Reputation: 2086
I'm confused after reading the documentation on what to expect when using Linq with a SortedList.
https://msdn.microsoft.com/en-us/library/ms132319(v=vs.110).aspx
I guess the enumeration is guaranteed to be sorted and also retrieve by index, but what about Values and Keys? Are all these cases safe?
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);
Upvotes: 0
Views: 1503
Reputation: 7783
If you look at the source code of Enumerable.cs, you will see that the overload without a predicate simply tries to treat the source as an IList and if that doesn't work, it returns the first element using the enumerator. Both the index and the enumerator are supposed to be handled internally by the SortedList class so that you get the appropriate (sorted) result:
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();
}
The overload with a predicate works slightly different in that it executes the predicate against every item using the enumerator, looking for the first match:
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();
}
Either way, you should be getting the same (sorted) result.
Upvotes: 0
Reputation: 4350
You can check out the source code here:
Apparently, the Keys
property is just a wrapper around an instance of this class:
If you look at the GetEnumerator()
method, you can see it creates a SortedListKeyEnumerator
. Here's the source code for that:
As far as I can tell, the MoveNext()
of this just iterates through the keys of the contained SortedList
.
You can find out the same way how Values
works.
Upvotes: 0
Reputation: 27609
Read the documentation...
From the documentation on the Values property:
"The order of the values in the
IList<T>
is the same as the order in theSortedList<TKey, TValue>
."
From the documentation on the Keys property:
"The order of the keys in the
IList<T>
is the same as the order in theSortedList<TKey, TValue>
."
Upvotes: 2