0

0

c# 如何遍历字典 dictionary

煙雲

煙雲

发布时间:2026-01-09 09:27:36

|

358人浏览过

|

来源于php中文网

原创

foreach遍历KeyValuePair是最安全常用方式,只读时性能最优;需删元素应先收集键再批量删除;仅需键或值时直接遍历Keys/Values更高效;复杂操作用LINQ但注意性能代价。

c# 如何遍历字典 dictionary

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

绝大多数时候,你只需要同时拿到键和值,foreach (var kvp in dict) 就是首选。它底层调用 GetEnumerator(),性能好、语义清晰、且编译器能做类型推导。

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

foreach (var kvp in ages) { Console.WriteLine($"Name: {kvp.Key}, Age: {kvp.Value}"); }

只取键或只取值?用 KeysValues 属性

当你确定只需要一边数据时,直接遍历 dict.Keysdict.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}");
}

foreach (int age in ages.Values) { Console.WriteLine($"Age: {age}"); }

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

这是新手最容易翻车的点:想删掉所有年龄小于 30 的人,结果写成 foreach 里直接 Remove,程序当场崩溃。

CG Faces
CG Faces

免费的 AI 人物图像素材网站

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

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);

foreach (var kvp in sorted) { Console.WriteLine($"{kvp.Key}: {kvp.Value}"); }

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

相关专题

更多
string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

315

2023.08.02

php中foreach用法
php中foreach用法

本专题整合了php中foreach用法的相关介绍,阅读专题下面的文章了解更多详细教程。

41

2025.12.04

string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

315

2023.08.02

int占多少字节
int占多少字节

int占4个字节,意味着一个int变量可以存储范围在-2,147,483,648到2,147,483,647之间的整数值,在某些情况下也可能是2个字节或8个字节,int是一种常用的数据类型,用于表示整数,需要根据具体情况选择合适的数据类型,以确保程序的正确性和性能。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

532

2024.08.29

c++怎么把double转成int
c++怎么把double转成int

本专题整合了 c++ double相关教程,阅读专题下面的文章了解更多详细内容。

51

2025.08.29

C++中int的含义
C++中int的含义

本专题整合了C++中int相关内容,阅读专题下面的文章了解更多详细内容。

193

2025.08.29

线程和进程的区别
线程和进程的区别

线程和进程的区别:线程是进程的一部分,用于实现并发和并行操作,而线程共享进程的资源,通信更方便快捷,切换开销较小。本专题为大家提供线程和进程区别相关的各种文章、以及下载和课程。

478

2023.08.10

console接口是干嘛的
console接口是干嘛的

console接口是一种用于在计算机命令行或浏览器开发工具中输出信息的工具,提供了一种简单的方式来记录和查看应用程序的输出结果和调试信息。本专题为大家提供console接口相关的各种文章、以及下载和课程。

411

2023.08.08

c++主流开发框架汇总
c++主流开发框架汇总

本专题整合了c++开发框架推荐,阅读专题下面的文章了解更多详细内容。

3

2026.01.09

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
10分钟--Midjourney创作自己的漫画
10分钟--Midjourney创作自己的漫画

共1课时 | 0.1万人学习

Midjourney 关键词系列整合
Midjourney 关键词系列整合

共13课时 | 0.9万人学习

AI绘画教程
AI绘画教程

共2课时 | 0.2万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号