您的位置:首页 >c#如何遍历字典中的key和value_c#遍历字典key和value详解
发布于2026-05-03 阅读(0)
扫一扫,手机访问

在C#中处理Dictionary时,遍历操作几乎是家常便饭。但方法选不对,轻则性能受损,重则直接抛出异常。简单来说,最稳妥的路径是直接用foreach遍历KeyValuePair;而单独遍历Keys或Values属性,不仅会丢失键值关联,还可能在不经意间引发并发修改问题。
这是最经典也最推荐的方式。它能在一次迭代中同时获取键和值,既避免了重复查找的开销,也天然规避了在遍历过程中修改字典可能导致的InvalidOperationException——当然,前提是你没有真的在循环体内去改动它。
来看一个标准示例:
var dict = new Dictionary{ ["a"] = 1, ["b"] = 2 }; foreach (var kvp in dict) { Console.WriteLine($"{kvp.Key} -> {kvp.Value}"); }
这里有个细节值得注意:循环变量kvp的类型是KeyValuePair,它并非一个匿名元组。因此,你不能直接使用C# 7+的元组解构语法写成var (key, value),而必须显式地访问kvp.Key和kvp.Value。
如果你偏爱var (key, value)这种简洁的解构写法,确实有办法实现,但需要绕个小弯。Dictionary的枚举器返回的是KeyValuePair,不是元组,所以得先转换一下。
dict.Select(kvp => (kvp.Key, kvp.Value))。这会将序列转换为匿名元组。不过,这引入了LINQ的延迟执行机制,并且每次访问都会创建一个新的元组对象,带来微小的性能开销。AsEnumerable()和Select来实现,思路类似。kvp.Key和kvp.Value反而是更优选择——它更直接、性能更好,而且避免了不必要的装箱操作。这是新手甚至老手都容易翻车的地方。当Dictionary正在被foreach遍历时,如果在循环体内直接调用Add、Remove或Clear等方法,运行时将立刻抛出InvalidOperationException,并提示“Collection was modified”。
var keysToRemove = dict.Where(x => x.Value < 0).Select(x => x.Key).ToList(); keysToRemove.ForEach(dict.Remove);for循环配合dict.Keys.ToList()(注意,ToList()会复制一份键的集合,会增加一些内存消耗)。Dictionary也可能遇到迭代器状态不可预测的问题。这时,ConcurrentDictionary才是正确的选择。dict.Keys和dict.Values返回的是字典键或值的只读视图。单独遍历它们本身没有问题,但需要注意两点:一是文档并未承诺其遍历顺序与另一侧完全一致(尽管当前实现通常是稳定的);二是它们只提供了单侧信息。
foreach (var key in dict.Keys)是完全合适的。Keys,再在循环内通过dict[key]查找,那性能就比不上直接遍历KeyValuePair了。因为每次dict[key]都是一次哈希查找,有开销,并且如果键不存在还会引发KeyNotFoundException。Values时同理:你完全丢失了键的上下文,无法进行反向查找,也不适用于需要键值配对的逻辑。还有一个容易被忽略的关键点:在标准的Dictionary中,遍历顺序并不等于插入顺序(即使在.NET Core 2.0+和.NET 5+中,默认行为也是如此)。如果你需要按插入顺序或特定顺序进行遍历,应当选择SortedDictionary、ImmutableSortedDictionary,或者自己维护一个List来保证顺序。
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
正版软件
正版软件
正版软件
正版软件
正版软件
1
2
3
7
9