首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >foreach Dictionary<>.Values或foreach Dictionary<>

foreach Dictionary<>.Values或foreach Dictionary<>
EN

Stack Overflow用户
提问于 2015-09-09 14:42:56
回答 4查看 4K关注 0票数 2

我想知道这两种在C#中迭代C#集合的风格的细节:

代码语言:javascript
复制
Dictionary<X, Y> xydic = new Dictionary<X, Y>();

风格一:

代码语言:javascript
复制
foreach (Y y in xydic.Values) { use y }

风格二:

代码语言:javascript
复制
foreach (var it in xydic) { Y y = it.Value; use y... }

我已经做C++开发人员多年了(现在我正在C#项目中工作),我不知道Dictionary集合是如何工作的,内存布局或者元素是如何迭代的,所以我想知道:

xydic.Values创建临时List<Y>?我在文献资料中没有看到任何关于创建临时列表的信息。

如果创建了一个临时列表,这不意味着这个集合会被迭代两次:首先创建List<Y>,第二次迭代列表本身?

如果以上问题的答案是肯定的,那么第二种风格应该更有效率,使第一种风格几乎毫无用处,所以我认为我在某些方面应该是错的。

我觉得这个问题应该在某个地方回答,但我找不到答案。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2015-09-09 14:54:34

检索.Values属性的Dictionary<,>是O(1)操作(记录在案)。嵌套类型Dictionary<,>.ValueCollection是字典的简单包装器,因此在创建它时不需要迭代。

在调用GetEnumerator()时,您将得到嵌套的嵌套Dictionary<,>.ValueCollection.Enumerator结构的实例。它直接通过private数组entries访问Dictionary<,>的条目。

你可以看到源代码

因此,上面的"Style one“是一种很好的、清晰的做事方式,没有任何性能开销。

请注意,获取值的顺序是任意的。您不知道底层数组entries是如何组织的,一旦Dictionary<,>在开始foreach之前有了许多插入和删除。

但是,使用“样式一”和“样式二”获得的顺序是相同的;它们都以相同的方式访问Dictionary<,>的私有Dictionary<,>数组。

票数 6
EN

Stack Overflow用户

发布于 2015-09-09 14:56:31

Values不是在创建List<T>,不是。它甚至没有将整组值拉到单独的数据结构中。它所做的就是创建一个可以迭代这些值的枚举数。它所做的事情与直接迭代字典时所做的完全相同;不同的是,与为每对对象构造一个KeyValuePair对象不同,它只给了一对对象的一半。除此之外,迭代过程是相同的。

票数 2
EN

Stack Overflow用户

发布于 2015-09-09 14:56:56

所有三个方法(KeysValues和字典的简单迭代)的行为都是相同的--迭代字典中的项的内部集合。没有创建额外的列表/数组。

唯一的“额外”工作是检查在迭代开始后是否修改了字典(整数比较)。

您可以在参考源中检查确切的细节。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32482656

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档