导读:本期聚焦于小宵创作的《C#如何使用泛型集合_C#中List和Dictionary用法【必会】》,敬请观看详情。泛型集合是C#开发中使用频率最高的数据结构,其中List和Dictionary更是绕不开的两个类。本文从非泛型集合的缺陷讲起,说明为什么推荐使用泛型版本,然后详细演示List的创建、增删改查、排序和遍历操作,接着深入Dictionary的键值对存取、常用方法以及遍历技巧,并对比两者在查找性能上的差异,最后给出实际开发中的选型建议和常见踩坑点。文中附带完整的代码示例,适合初学者快速上手,也适合有基础的读者查漏补缺。

在C#的日常开发中,泛型集合几乎是每个项目都会用到的东西。相比早期的ArrayList和Hashtable,泛型集合List<T>和Dictionary<TKey, TValue>在类型安全和性能上都有明显优势。本文将系统地讲解这两个集合的用法,包括创建、增删改查、遍历、排序以及使用中的注意事项,帮助你彻底掌握这个必会知识点。

C#如何使用泛型集合_C#中List和Dictionary用法【必会】

为什么使用泛型集合而不是非泛型集合

在泛型出现之前,.NET提供了ArrayList这样的集合类。ArrayList内部存储的是object类型,往里面添加任何值类型的数据都会发生装箱操作,读取时又要拆箱,这两步操作都会带来性能损耗。更麻烦的是类型安全问题:你可以往同一个ArrayList里既放int又放string,编译器不会报错,但取出来使用时一旦类型转换失败,程序就会在运行时抛出InvalidCastException。

泛型集合的出现就是为了解决这两个问题。List<int>在声明时就明确了元素类型,编译器会强制检查所有添加进来的元素,类型不匹配直接编译不通过,把潜在的运行时错误提前到了编码阶段。同时由于类型确定,值类型不再需要装箱拆箱,在大量数据的场景下性能差距可以达到数倍。因此现在开发中一律推荐使用System.Collections.Generic命名空间下的泛型集合。

List<T>的常用操作详解

List<T>是最常用的有序集合,底层基于数组实现,支持通过下标快速访问。先看一组基础操作代码:

List<string> names = new List<string>();
// 添加元素
names.Add("张三");
names.AddRange(new[] { "李四", "王五" });
// 插入元素到指定位置
names.Insert(0, "赵六");
// 判断是否包含某个元素
bool exists = names.Contains("张三");
// 查找元素下标
int index = names.IndexOf("李四");
// 移除元素
names.Remove("张三");
// 移除指定下标的元素
names.RemoveAt(0);
// 获取元素个数
int count = names.Count;
// 下标访问
string first = names[0];

遍历List有两种常见方式,一种是for循环配合下标,一种是foreach。如果遍历过程中不需要修改集合,推荐用foreach,代码更简洁;如果需要按下标操作或者遍历中要移除元素,则要用for循环并注意倒序遍历。需要特别提醒的是,在foreach循环中直接对集合做Add或Remove操作会抛出InvalidOperationException异常,这是初学者非常容易踩的坑。如果要边遍历边筛选,可以先使用FindAll返回新集合,或者用倒序的for循环删除。

排序方面,可以调用Sort方法配合lambda表达式,也可以使用LINQ的OrderBy。两者的区别在于Sort是在原集合上就地排序,而OrderBy返回的是新的排序结果,原集合顺序不变。对于自定义类型,还可以让类实现IComparable<T>接口,或者在Sort时传入Comparison委托:

List<int> nums = new List<int> { 5, 2, 8, 1 };
nums.Sort();                          // 升序:1 2 5 8
nums.Sort((a, b) => b.CompareTo(a)); // 降序:8 5 2 1
nums.Reverse();                       // 反转

Dictionary<TKey, TValue>的用法与技巧

Dictionary也就是常说的字典或哈希表,以键值对的形式存储数据,底层基于哈希算法实现,通过key查找value的平均时间复杂度接近O(1),非常适合需要频繁根据某个标识快速定位数据的场景。基础用法如下:

Dictionary<int, string> userDict = new Dictionary<int, string>();
// 添加键值对
userDict.Add(1, "管理员");
userDict[2] = "普通用户";   // 下标方式添加或覆盖
// 读取,key不存在会抛异常
string role = userDict[1];
// 安全读取,key不存在返回默认值
userDict.TryGetValue(3, out string value);
// 判断是否包含某个key
bool hasKey = userDict.ContainsKey(2);
// 移除
userDict.Remove(1);
// 个数
int n = userDict.Count;

使用Dictionary有几个高频踩坑点需要记住。第一,key必须唯一,对已存在的key调用Add会抛出ArgumentException异常,但用下标赋值的方式是安全的,它会直接覆盖旧值。第二,直接用下标读取一个不存在的key会抛出KeyNotFoundException,所以在不确定key是否存在时,应该优先使用TryGetValue方法,它一次哈希查找就能同时完成判断和取值,比先ContainsKey再取值的写法效率更高。第三,作为key的类型如果是我们自定义的类,需要正确重写GetHashCode和Equals方法,否则默认按引用比较,两个内容相同的对象会被当成不同的key。

遍历字典时,可以遍历KeyValuePair结构,也可以分别遍历Keys和Values属性。如果遍历过程中需要修改字典,同样需要先把要处理的数据缓存到临时列表中再操作:

foreach (KeyValuePair<int, string> kv in userDict)
{
    Console.WriteLine($"key={kv.Key}, value={kv.Value}");
}
foreach (var key in userDict.Keys)
{
    Console.WriteLine(key);
}

如何选择以及性能对比

List和Dictionary各有适用场景,核心判断依据是你要按什么方式访问数据。如果数据是有序的一批记录,主要做顺序遍历、按下标访问或者尾部追加,用List更合适;如果数据是一对一的映射关系,需要频繁根据key快速查找,用Dictionary明显更快。举个典型例子:有一万条用户数据,要根据用户ID反复查找用户信息,用List每次查找平均要比较五千次,而用Dictionary只需一次哈希定位,性能差距在这种数据量下会非常直观。

另外提两点实践建议。一是集合初始化时如果能预估数据量,可以通过构造函数传入初始容量,比如new List<string>(1000),这样可以减少内部数组自动扩容带来的复制开销。二是在多线程环境下,List和Dictionary都不是线程安全的,并发读写应使用System.Collections.Concurrent命名空间下的ConcurrentDictionary等类型,或者用锁加以保护。掌握这些要点后,遇到集合选型和性能问题就能从容应对了。

C#泛型集合List用法Dictionary用法修改时间:2026-09-13 20:50:42

免责声明:已尽一切努力确保本网站所含信息的准确性。网站作品多为原创整理与精心创作,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们进行处理Email:chomcom@qq.com。
引用或转载本作品时,请注明当前出处:https://www.ipipp.com/html/20260913/56237.html,基于非商业用途的前提下,欢迎转载或二创本作品。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。