news 2026/10/19 8:10:32

C# 集合全面指南:种类、遍历、用法与注意事项

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
C# 集合全面指南:种类、遍历、用法与注意事项

一、C# 集合概述

C# 中的集合是用于存储和管理一组相关对象的特殊类,它们提供了比数组更强大的功能,如动态大小调整、排序、搜索等。

二、集合的主要种类

1.非泛型集合 (System.Collections)

// 已过时,不推荐在新项目中使用 ArrayList list = new ArrayList(); list.Add(1); // 可以添加任何类型 list.Add("string"); // 类型不安全

2.泛型集合 (System.Collections.Generic)-推荐使用

列表类集合
// List<T> - 最常用的动态数组 List<string> fruits = new List<string> { "Apple", "Banana", "Orange" }; fruits.Add("Mango"); fruits.Remove("Banana"); // LinkedList<T> - 双向链表 LinkedList<int> numbers = new LinkedList<int>(); numbers.AddLast(1); numbers.AddFirst(0); // ObservableCollection<T> - 支持数据绑定和通知 ObservableCollection<string> items = new ObservableCollection<string>(); items.CollectionChanged += (sender, e) => { Console.WriteLine("集合已更改"); };
字典类集合
// Dictionary<TKey, TValue> - 哈希表实现的键值对 Dictionary<string, int> ages = new Dictionary<string, int> { ["Alice"] = 25, ["Bob"] = 30 }; ages["Charlie"] = 28; // SortedDictionary<TKey, TValue> - 基于二叉搜索树的有序字典 SortedDictionary<int, string> sortedDict = new SortedDictionary<int, string>(); // ConcurrentDictionary<TKey, TValue> - 线程安全的字典 ConcurrentDictionary<string, int> concurrentDict = new ConcurrentDictionary<string, int>();
队列和栈
// Queue<T> - 先进先出(FIFO) Queue<string> queue = new Queue<string>(); queue.Enqueue("First"); queue.Enqueue("Second"); string firstItem = queue.Dequeue(); // Stack<T> - 后进先出(LIFO) Stack<int> stack = new Stack<int>(); stack.Push(1); stack.Push(2); int topItem = stack.Pop();
集合类
// HashSet<T> - 不包含重复元素的高性能集合 HashSet<int> uniqueNumbers = new HashSet<int> { 1, 2, 2, 3 }; // 结果: 1, 2, 3 // SortedSet<T> - 有序的不重复集合 SortedSet<string> sortedSet = new SortedSet<string>(); // ReadOnlyCollection<T> - 只读集合包装器 IReadOnlyList<string> readOnlyList = fruits.AsReadOnly();

不可变集合 (System.Collections.Immutable)

// 线程安全且不可变的集合 ImmutableList<string> immutableList = ImmutableList.Create("A", "B", "C"); ImmutableDictionary<string, int> immutableDict = ImmutableDictionary.Create<string, int>();

三、集合的遍历方式

1.foreach 循环 (推荐)

foreach (var fruit in fruits) { Console.WriteLine(fruit); } // 遍历字典 foreach (KeyValuePair<string, int> kvp in ages) { Console.WriteLine($"{kvp.Key}: {kvp.Value}"); }

2.for 循环 (适用于需要索引的情况)

for (int i = 0; i < fruits.Count; i++) { Console.WriteLine($"索引 {i}: {fruits[i]}"); }

四、常见用法示例

1.集合初始化

// 多种初始化方式 List<int> numbers1 = new List<int> { 1, 2, 3 }; List<int> numbers2 = new() { 1, 2, 3 }; // C# 9.0 var numbers3 = new List<int> { 1, 2, 3 }; // 字典初始化 var dict1 = new Dictionary<string, int> { { "Alice", 25 }, { "Bob", 30 } }; var dict2 = new Dictionary<string, int> { ["Alice"] = 25, ["Bob"] = 30 };

2.集合操作

// 添加元素 fruits.Add("Grape"); fruits.AddRange(new[] { "Peach", "Pear" }); fruits.Insert(1, "Lemon"); // 删除元素 fruits.Remove("Apple"); fruits.RemoveAt(0); fruits.RemoveAll(f => f.StartsWith("A")); // 查找元素 bool hasApple = fruits.Contains("Apple"); int index = fruits.IndexOf("Banana"); var apple = fruits.Find(f => f == "Apple"); // 排序 fruits.Sort(); fruits.Sort((x, y) => x.Length.CompareTo(y.Length)); // 转换数组 string[] fruitArray = fruits.ToArray(); List<string> fruitList = fruitArray.ToList();

3.性能优化操作

// 预设容量提升性能 List<string> largeList = new List<string>(10000); // 批量操作 List<int> source = Enumerable.Range(1, 10000).ToList(); List<int> destination = new List<int>(source.Count); destination.AddRange(source);

五、重要注意事项

1.集合选择指南

选择原则: - 需要快速随机访问 → List<T> - 频繁插入/删除 → LinkedList<T> - 键值对存储 → Dictionary<TKey, TValue> - 需要排序 → SortedDictionary<TKey, TValue> - 去重 → HashSet<T> - 线程安全 → ConcurrentBag/Queue/Stack/Dictionary - 只读 → ReadOnlyCollection<T> - 不可变 → ImmutableList/Dictionary

2.遍历时修改集合的陷阱

// 遍历时直接修改会抛出InvalidOperationException foreach (var fruit in fruits) { if (fruit == "Apple") fruits.Remove(fruit); // 运行时错误! } // 正确做法1:使用ToArray()副本 foreach (var fruit in fruits.ToArray()) { if (fruit == "Apple") fruits.Remove(fruit); } // 正确做法2:使用for循环反向遍历 for (int i = fruits.Count - 1; i >= 0; i--) { if (fruits[i] == "Apple") fruits.RemoveAt(i); } // 正确做法3:先标记后删除 var itemsToRemove = new List<string>(); foreach (var fruit in fruits) { if (fruit == "Apple") itemsToRemove.Add(fruit); } foreach (var item in itemsToRemove) { fruits.Remove(item); }

3.字典使用注意事项

Dictionary<string, int> dict = new Dictionary<string, int>(); // 错误:访问不存在的键 int value = dict["nonexistent"]; // KeyNotFoundException // 正确:使用TryGetValue if (dict.TryGetValue("Alice", out int age)) { Console.WriteLine(age); } // 正确:使用ContainsKey检查 if (dict.ContainsKey("Alice")) { value = dict["Alice"]; } // 字典键的自定义类型需要正确实现GetHashCode和Equals public class Person { public string Name { get; set; } public override bool Equals(object obj) => obj is Person other && Name == other.Name; public override int GetHashCode() => Name?.GetHashCode() ?? 0; }

4.性能注意事项

// List<T>的容量管理 List<int> list = new List<int>(); for (int i = 0; i < 1000; i++) { list.Add(i); // 多次重新分配内存 // 如果知道大小,预设容量 List<int> optimizedList = new List<int>(1000); } // HashSet<T> vs List<T>的Contains性能 HashSet<string> hashSet = new HashSet<string>(); // O(1) List<string> normalList = new List<string>(); // O(n)

5.线程安全

// 非线程安全 List<string> unsafeList = new List<string>(); // 使用锁 object lockObj = new object(); lock (lockObj) { unsafeList.Add("item"); } // 使用并发集合 ConcurrentBag<string> safeBag = new ConcurrentBag<string>(); safeBag.Add("item");

6.内存管理

// 及时清理不再使用的集合 List<byte[]> largeData = new List<byte[]>(); // 使用后清理 largeData.Clear(); largeData.TrimExcess(); // 释放多余容量 // 使用using语句处理需要释放资源的集合 using (BlockingCollection<int> collection = new BlockingCollection<int>()) { // 使用集合 }

7.空值处理

// 处理可能的null集合 List<string> possibleNullList = GetList(); var count = possibleNullList?.Count ?? 0; // 安全访问 // 使用空集合代替null public List<string> GetItems() { return new List<string>(); // 而不是返回null }

六、总结

  1. 优先使用泛型集合,避免非泛型集合

  2. 根据场景选择合适的集合类型

  3. 遍历时避免修改集合内容

  4. 合理预设集合容量提升性能

  5. 及时释放不再使用的集合

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/18 7:43:38

Excalidraw实现KANO模型:需求优先级排序

Excalidraw实现KANO模型&#xff1a;需求优先级排序 在产品管理的日常实践中&#xff0c;我们常面临这样一个困境&#xff1a;用户反馈如潮水般涌来&#xff0c;功能需求清单越拉越长&#xff0c;但资源有限、时间紧迫&#xff0c;到底该先做哪个&#xff1f;传统的优先级排序工…

作者头像 李华
网站建设 2026/10/18 5:09:40

基于Java+大数据+SSMB站数据分析可视化系统(源码+LW+调试文档+讲解等)/B站数据可视化/B站数据分析/B站分析系统/数据可视化系统/数据分析系统/B站数据平台/B站可视化工具

博主介绍 &#x1f497;博主介绍&#xff1a;✌全栈领域优质创作者&#xff0c;专注于Java、小程序、Python技术领域和计算机毕业项目实战✌&#x1f497; &#x1f447;&#x1f3fb; 精彩专栏 推荐订阅&#x1f447;&#x1f3fb; 2025-2026年最新1000个热门Java毕业设计选题…

作者头像 李华
网站建设 2026/10/17 5:34:33

基于Python+大数据+SSMCBA球员数据可视化分析系统(源码+LW+调试文档+讲解等)/CBA球员数据展示系统/CBA球员数据统计系统/CBA球员数据分析平台/篮球数据可视化分析系统

博主介绍 &#x1f497;博主介绍&#xff1a;✌全栈领域优质创作者&#xff0c;专注于Java、小程序、Python技术领域和计算机毕业项目实战✌&#x1f497; &#x1f447;&#x1f3fb; 精彩专栏 推荐订阅&#x1f447;&#x1f3fb; 2025-2026年最新1000个热门Java毕业设计选题…

作者头像 李华
网站建设 2026/10/19 7:04:16

Excalidraw导出PDF注意事项:格式保持完整

Excalidraw导出PDF注意事项&#xff1a;格式保持完整 在技术团队的日常协作中&#xff0c;一张架构图往往胜过千言万语。无论是向客户汇报系统设计&#xff0c;还是在站会上快速勾勒服务调用链路&#xff0c;可视化表达早已成为工程师沟通的“第二语言”。而随着远程办公常态化…

作者头像 李华
网站建设 2026/10/19 4:40:33

【C++】优选算法必修篇之双指针实战:移动零 复写零

应用场景 在算法中&#xff0c;双指针&#xff08;Two Pointers&#xff09; 是一种极具代表性的高效技巧。它通过维护两个索引或指针&#xff0c;在一次遍历中完成双层循环才能解决的问题&#xff0c;从而显著降低时间复杂度。常见的双指针形态主要分为两类&#xff1a;对撞指…

作者头像 李华
网站建设 2026/10/19 7:24:29

【C++】继承深度解析:继承方式和菱形虚拟继承的详解

一、继承方式1. 单继承一个派生类只有一个直接基类的时候称这个继承为单继承 Person ↓ Teacher ↓ Student &#xff08;单链&#xff09;代码语言&#xff1a;javascriptAI代码解释// 基类&#xff1a;人 class Person { public:string name;int age;void ShowPerson(){cout …

作者头像 李华