C# 常用集合类型详解

张开发
2026/4/15 4:38:31 15 分钟阅读

分享文章

C# 常用集合类型详解
前言C# 中提供了多种集合类型每种都有各自的适用场景。本文将通过对比和代码示例帮你理清它们的区别和用法。一、整体对比类型命名空间类型安全动态大小访问方式适用场景数组[]System✅ 安全❌ 固定下标数量固定ArrayListSystem.Collections❌ 不安全✅ 动态下标老项目兼容ListTSystem.Collections.Generic✅ 安全✅ 动态下标现代开发首选DictionaryK,VSystem.Collections.Generic✅ 安全✅ 动态键键值对查找HashtableSystem.Collections❌ 不安全✅ 动态键老项目兼容StackTSystem.Collections.Generic✅ 安全✅ 动态LIFO后进先出QueueTSystem.Collections.Generic✅ 安全✅ 动态FIFO先进先出HashSetTSystem.Collections.Generic✅ 安全✅ 动态无重复去重/集合运算二、各类型详解1. 数组[]—— 固定长度的基础特点长度固定性能最好但不够灵活。csharp// 创建数组 int[] arr new int[5]; // 长度5全部初始化为0 int[] arr2 { 1, 2, 3, 4, 5 }; // 修改元素 arr2[0] 10; // 遍历 foreach (var item in arr2) { Console.WriteLine(item); }易错点数组长度固定超出索引会报错。csharpint[] arr new int[3]; arr[3] 10; // ❌ IndexOutOfRangeException2.ArrayList—— 不推荐使用特点可以存任意类型但需要装箱拆箱性能差。csharpArrayList list new ArrayList(); list.Add(123); // int → object装箱 list.Add(hello); // 可以混搭类型 list.Add(3.14); int num (int)list[0]; // object → int拆箱易错点类型不安全运行时可能出错。csharpArrayList list new ArrayList(); list.Add(123); string str (string)list[0]; // ❌ 编译通过运行时报错3.ListT—— 现代开发首选 ⭐特点类型安全无需装箱拆箱性能好。csharpListint list new Listint(); list.Add(10); list.Add(20); list.Add(30); // 索引访问 Console.WriteLine(list[1]); // 20 // 插入 list.Insert(1, 15); // [10,15,20,30] // 删除 list.Remove(20); // [10,15,30] list.RemoveAt(0); // [15,30] // 遍历 foreach (var item in list) { Console.WriteLine(item); }易错点遍历时不要删除元素。csharpListint list new Listint { 1, 2, 3 }; foreach (var item in list) { if (item 2) list.Remove(item); // ❌ 运行时错误 } // ✅ 正确做法倒序遍历或用 RemoveAll list.RemoveAll(x x 2);4.DictionaryK,V—— 键值对查找特点通过键快速查找值时间复杂度 O(1)。csharpDictionarystring, int scores new Dictionarystring, int(); scores.Add(张三, 85); scores.Add(李四, 92); scores[王五] 78; // 另一种添加方式 // 取值推荐用 TryGetValue if (scores.TryGetValue(张三, out int score)) { Console.WriteLine($张三的成绩{score}); } // 遍历 foreach (var kvp in scores) { Console.WriteLine(${kvp.Key}: {kvp.Value}); }易错点用[]取值时键不存在会报错。csharpint val scores[赵六]; // ❌ KeyNotFoundException // ✅ 用 TryGetValue 或 ContainsKey if (scores.ContainsKey(赵六)) { int val scores[赵六]; }5.Hashtable—— 不推荐使用特点Dictionary的前身非泛型类型不安全。csharpHashtable ht new Hashtable(); ht.Add(name, 张三); ht.Add(age, 18); string name (string)ht[name]; // 需要强转建议新项目一律使用DictionaryTKey, TValue6.StackT—— 后进先出LIFO特点最后进去的最先出来。像叠盘子。csharpStackstring stack new Stackstring(); stack.Push(第一张); stack.Push(第二张); stack.Push(第三张); string top stack.Pop(); // 第三张取出并移除 string peek stack.Peek(); // 第二张只看不取 foreach (var item in stack) { Console.WriteLine(item); // 第二张 → 第一张 }应用场景撤销操作、括号匹配、函数调用。7.QueueT—— 先进先出FIFO特点先进去的最先出来。像排队。csharpQueuestring queue new Queuestring(); queue.Enqueue(第一个人); queue.Enqueue(第二个人); queue.Enqueue(第三个人); string first queue.Dequeue(); // 第一个人 string front queue.Peek(); // 第二个人只看不取 foreach (var item in queue) { Console.WriteLine(item); // 第二个人 → 第三个人 }应用场景消息队列、任务调度、打印机任务。8.HashSetT—— 不重复集合特点元素唯一自动去重。csharpHashSetint set new HashSetint(); set.Add(1); set.Add(2); set.Add(2); // 不会报错但不会重复添加 set.Add(3); Console.WriteLine(set.Count); // 3 // 集合运算 HashSetint set1 new HashSetint { 1, 2, 3 }; HashSetint set2 new HashSetint { 2, 3, 4 }; set1.IntersectWith(set2); // 交集 → {2, 3} set1.UnionWith(set2); // 并集 → {1, 2, 3, 4} set1.ExceptWith(set2); // 差集 → {1}三、综合运用示例下面是一个学生成绩管理系统的简单示例综合运用了多种集合类型csharpusing System; using System.Collections.Generic; using System.Linq; class Student { public int Id { get; set; } public string Name { get; set; } public int Score { get; set; } } class Program { static void Main() { // 1. ListT 存储学生列表 ListStudent students new ListStudent { new Student { Id 1, Name 张三, Score 85 }, new Student { Id 2, Name 李四, Score 92 }, new Student { Id 3, Name 王五, Score 78 }, new Student { Id 4, Name 赵六, Score 85 } }; // 2. Dictionary 快速查找学生 Dictionaryint, Student dict students.ToDictionary(s s.Id, s s); Console.Write(请输入学号); if (int.TryParse(Console.ReadLine(), out int id)) { if (dict.TryGetValue(id, out Student stu)) { Console.WriteLine($找到学生{stu.Name}成绩{stu.Score}); } else { Console.WriteLine(学生不存在); } } // 3. Stack 模拟撤销操作 Stackstring undoStack new Stackstring(); undoStack.Push(添加学生张三); undoStack.Push(修改李四成绩); undoStack.Push(删除王五); Console.WriteLine($\n撤销{undoStack.Pop()}); // 删除王五 Console.WriteLine($撤销{undoStack.Pop()}); // 修改李四成绩 // 4. Queue 模拟处理请求 Queuestring requestQueue new Queuestring(); requestQueue.Enqueue(查询学生); requestQueue.Enqueue(修改成绩); requestQueue.Enqueue(导出数据); Console.WriteLine(\n处理请求); while (requestQueue.Count 0) { Console.WriteLine($→ {requestQueue.Dequeue()}); } // 5. HashSet 去重统计分数 HashSetint scoreSet new HashSetint(); foreach (var s in students) { scoreSet.Add(s.Score); } Console.WriteLine($\n分数种类{string.Join(,, scoreSet)}); // 85,92,78 } }四、选择指南需求推荐使用数量固定数组[]动态增加按位置访问ListT按键快速查找DictionaryK,V后进先出StackT先进先出QueueT自动去重HashSetT需要兼容老代码ArrayList或Hashtable不推荐新项目五、易错点总结易错点说明数组越界索引超出Length-1遍历时删除foreach中不能修改集合用for倒序或RemoveAllDictionary 取值用[]键不存在会抛异常用TryGetValueArrayList 类型转换取出的元素需要强转容易出错Stack/Queue 空集合Pop()或Dequeue()前要检查Count 0六、一句话总结数组定长List动字典查找最快用。栈后进先队列先HashSet去重真轻松。本文为个人学习总结欢迎交流讨论

更多文章