Pap*_*ter 2 c# iteration foreach containers
我想知道DictionaryC#中这两种迭代集合样式的细节:
Dictionary<X, Y> xydic = new Dictionary<X, Y>();
Run Code Online (Sandbox Code Playgroud)
款式一:
foreach (Y y in xydic.Values) { use y }
Run Code Online (Sandbox Code Playgroud)
款式二:
foreach (var it in xydic) { Y y = it.Value; use y... }
Run Code Online (Sandbox Code Playgroud)
我多年来一直是 C++ 开发人员(现在我在一个 C# 项目中工作),但我不知道Dictionary集合如何工作、内存布局或元素如何迭代的细节,所以我想知道:
xydic.Values创建一个临时List<Y>? 我在文档中没有看到有关创建临时列表的任何信息。
如果创建了一个临时列表,这是否意味着该集合被迭代两次:第一次创建List<Y>,第二次迭代列表本身?
如果上述问题的答案是肯定的,那么第二种风格应该更有效,使第一种风格几乎无用,所以我认为我在某种程度上应该是错误的。
我觉得这个问题应该在某个地方得到回答,但我找不到答案。
检索 a 的.Values属性Dictionary<,>是一个 O(1) 操作(记录)。嵌套类型Dictionary<,>.ValueCollection是字典的简单包装器,因此在创建它时没有迭代。
在调用 时GetEnumerator(),您将获得嵌套的嵌套Dictionary<,>.ValueCollection.Enumerator结构的实例。它直接通过acccesses条目private阵列entries的Dictionary<,>。
你可以看到源代码。
所以你上面的“风格一”是一种很好的、清晰的做事方式,没有性能开销。
请注意,获取值的顺序是任意的。您不知道底层数组entries是如何组织的,一旦在Dictionary<,>开始之前进行了多次插入和删除foreach。
但是,“样式一”和“样式二”的顺序是相同的;两者都以相同的方式访问 的私有entries数组Dictionary<,>。