10

当我SortedDictionary<TK, TV>在.NET中并且我想枚举它时,ICollection<KeyValuePair<TK, TV>>它是否按预期顺序枚举?

那就是KeyValuePair<TK, TV>最低键首先返回,然后是KeyValuePair<TK, TV>第二低键等?

注意:仅接受由参考支持的答案。

4

3 回答 3

11

来自 GetEnumerator 的参考

“字典使用内部树以排序顺序维护。每个新元素都位于正确的排序位置,并且每当删除元素时,都会调整树以保持排序顺序。在枚举时,排序顺序保持不变。 "

具体来说:“在枚举时,排序顺序保持不变。”

于 2011-04-23T16:48:23.357 回答
4

是的,当然,尽管您会发现很难找到准确说明这一点的文档。

尽管该类型的四个重载中的每一个的文档都GetEnumerator对返回“遍历集合的枚举器”做出了模糊的陈述,但很明显它们应该产生等效的(按键排序)序列;请记住,排序字典旨在“表示按键排序的键/值对的集合”。例如,如果一个集合在循环和 LINQ to Objects 查询之间的行为完全不同(即具有不同的枚举顺序),那么用户会非常不直观和困惑。foreach

我能做的最好的就是为您提供GetEnumerator您似乎感兴趣的两种方法的实现(从 .NET 4.0 开始)。它们是相同的——它们返回嵌套Enumerator类型的实例,其构造函数具有相同的参数。唯一的区别是第二个重载中结构类型的装箱:

// Used when you do foreach(var kvp in dict) { ... }

public Enumerator<TKey, TValue> GetEnumerator()
{
    return new Enumerator<TKey, TValue>
                ((SortedDictionary<TKey, TValue>) this, 1);
}

// Used when you do:
// foreach(var kvp in (ICollection<KeyValuePair<TKey, TValue>>)dict) { ... }
// or use LINQ to Objects on the collection.

IEnumerator<KeyValuePair<TKey, TValue>> 
IEnumerable<KeyValuePair<TKey, TValue>>.GetEnumerator()
{
    return new Enumerator<TKey, TValue>
                ((SortedDictionary<TKey, TValue>) this, 1);
}

事实上,唯一实现稍有不同的GetEnumerator重载是方法。这会更改构造函数调用的参数,以便生成的枚举器生成实例而不是实例。当然,枚举顺序仍然与其他重载相同。IDictionary.GetEnumeratorDictionaryEntryKeyValuePair<,>

于 2011-04-23T16:18:19.653 回答
1

这取决于IComparer密钥的默认实现,假设您没有传入一个:

SortedDictionary(Of TKey, TValue) 需要一个比较器实现来执行键比较。您可以使用接受比较器参数的构造函数来指定 IComparer(Of T) 泛型接口的实现;如果未指定实现,则使用默认的通用比较器 Comparer(Of T).Default。如果类型 TKey 实现 System.IComparable(Of T) 泛型接口,则默认比较器使用该实现。

查看页面的Remarks部分SortedDictionary<TKey, TValue>

因此,如果您的键是 a string,则将使用的字符串实现IComparable,如果int32int32使用实现。

于 2011-04-23T16:01:15.220 回答