c# 如何遍历字典 dictionary

来源:这里教程网 时间:2026-02-21 17:37:25 作者:

直接用
foreach
遍历
KeyValuePair
是最安全、最常用的方式

绝大多数时候,你只需要同时拿到键和值,

foreach (var kvp in dict)
就是首选。它底层调用
GetEnumerator()
,性能好、语义清晰、且编译器能做类型推导。

不要写
foreach (var item in dict)
后再猜
item
类型——虽然能运行,但可读性差;明确写成
KeyValuePair<string int></string>
或继续用
var
(C# 6+ 推荐)更稳妥
别在循环体里调
dict.Remove(key)
dict.Add(...)
,会立刻抛
InvalidOperationException: Collection was modified
如果字典很大(比如 >10 万项),且只读遍历,
foreach
仍是最快方式;比先转
ToList()
for
省内存也省时间
Dictionary<string, int> ages = new Dictionary<string, int>
{
    {"Alice", 25},
    {"Bob", 30},
    {"Charlie", 35}
};
<p>foreach (var kvp in ages)
{
Console.WriteLine($"Name: {kvp.Key}, Age: {kvp.Value}");
}

只取键或只取值?用
Keys
Values
属性

当你确定只需要一边数据时,直接遍历

dict.Keys
dict.Values
更高效,避免构造无用的
KeyValuePair
对象。

dict.Keys
返回
KeyCollection
,是只读视图,修改原字典后它自动反映变化
注意:
foreach (string key in dict.Keys)
中若后续要用
dict[key]
,得确保键存在——虽然字典遍历时键必然存在,但若你在循环中删了它,下一次访问可能出错(所以还是推荐先缓存要删的键)
不建议为了“看起来整齐”而统一用
dict.Keys.ToList()
再遍历——除非你真需要顺序或反复访问
foreach (string name in ages.Keys)
{
    Console.WriteLine($"Name: {name}");
}
<p>foreach (int age in ages.Values)
{
Console.WriteLine($"Age: {age}");
}

需要边遍历边删元素?先收集键,再批量删

这是新手最容易翻车的点:想删掉所有年龄小于 30 的人,结果写成

foreach
里直接
Remove
,程序当场崩溃。

正确做法是用 LINQ 先筛选出要删的键:
dict.Where(kvp => kvp.Value  kvp.Key).ToList()
必须调
.ToList()
—— 如果只用
.ToArray()
或不转集合,延迟执行会导致遍历时字典被改,依然报错
如果你用的是 .NET 6+,也可以考虑
dict.RemoveAll(kvp => kvp.Value (需引用 <code>System.Linq
),但注意这方法不是
Dictionary
原生 API,而是 LINQ 扩展,本质仍是两趟操作
var keysToRemove = ages
    .Where(kvp => kvp.Value < 30)
    .Select(kvp => kvp.Key)
    .ToList();
<p>foreach (string key in keysToRemove)
{
ages.Remove(key);
}

要排序、过滤或并行处理?上 LINQ,但注意性能代价

当需求超出简单遍历,比如“按值降序输出”或“多核处理大字典”,LINQ 很方便,但它会创建中间集合,有开销。

dict.OrderBy(kvp => kvp.Value)
返回
IOrderedEnumerable
,不是新字典;遍历时才真正排序,但每次
foreach
都会重排——如需复用,加
.ToList()
Parallel.ForEach(dict.AsParallel(), ...)
适合 CPU 密集型处理(比如对每个值做哈希计算),但对简单打印或 IO 操作反而拖慢,还可能引发线程安全问题(比如共享
Console.WriteLine
永远别在 LINQ 查询里写
dict[key]
——它已经给你
kvp
了,再查一次是冗余开销
var sorted = ages
    .OrderByDescending(kvp => kvp.Value)
    .ThenBy(kvp => kvp.Key);
<p>foreach (var kvp in sorted)
{
Console.WriteLine($"{kvp.Key}: {kvp.Value}");
}

实际项目里,95% 的遍历场景用第一个

foreach
就够了。剩下那 5%,往往不是“怎么遍历”的问题,而是“要不要遍历”——比如是否该用索引结构、是否该提前建好视图、或者干脆换用
SortedDictionary
。别让遍历逻辑掩盖了数据建模的根本问题。

相关推荐