差别
这里会显示出您选择的修订版和当前版本之间的差别。
| 两侧同时换到之前的修订记录 前一修订版 | |||
| csharp:集合 [2025/11/25 09:14] – 移除 - 外部编辑 (未知日期) 127.0.0.1 | csharp:集合 [2025/11/25 09:14] (当前版本) – ↷ 页面名由csharp:list改为csharp:集合 张叶安 | ||
|---|---|---|---|
| 行 1: | 行 1: | ||
| + | ====== C# 集合 (Collections) 详解 ====== | ||
| + | 在 C# 中,集合用于存储和管理对象组。根据是否支持泛型(Generic),主要分为两大类: | ||
| + | * **泛型集合** (``System.Collections.Generic``): | ||
| + | * **非泛型集合** (``System.Collections``): | ||
| + | |||
| + | ===== 1. List< | ||
| + | |||
| + | ``List< | ||
| + | |||
| + | ==== 1.1 引用命名空间 ==== | ||
| + | 在使用 List 之前,必须引用以下命名空间: | ||
| + | <code csharp> | ||
| + | using System.Collections.Generic; | ||
| + | </ | ||
| + | |||
| + | ==== 1.2 定义与初始化 ==== | ||
| + | 声明 List 时必须指定数据类型(T)。 | ||
| + | |||
| + | <code csharp> | ||
| + | // 1. 声明并实例化一个空的 List | ||
| + | List< | ||
| + | |||
| + | // 2. 使用集合初始化器 (声明时直接赋值) | ||
| + | var list2 = new List< | ||
| + | |||
| + | // 3. 添加元素演示 | ||
| + | List< | ||
| + | list.Add(2); | ||
| + | list.Add(2); | ||
| + | list.Add(3); | ||
| + | |||
| + | // 4. 读取与计算 | ||
| + | int k = 8; | ||
| + | int b; | ||
| + | Console.WriteLine(list[2] + k); // 输出 11 (3 + 8) | ||
| + | Console.WriteLine(b = list[0]); | ||
| + | Console.WriteLine(b = list[0] + list[1]); // 输出 4 (2 + 2) | ||
| + | </ | ||
| + | |||
| + | ==== 1.3 常用属性与方法 ==== | ||
| + | |||
| + | 假设 ``var list = new List< | ||
| + | |||
| + | ^ 属性/ | ||
| + | | **Count** | 获取实际包含的元素个数 | ``int c = list.Count; | ||
| + | | **Capacity** | 获取内部数据结构的容量(通常大于等于 Count) | ``int cap = list.Capacity; | ||
| + | | **Add** | 在列表末尾添加一个元素 | ``list.Add(100); | ||
| + | | **Contains** | 判断元素是否存在,返回 bool | ``bool has5 = list.Contains(5); | ||
| + | | **Clear** | 清空所有元素 | ``list.Clear(); | ||
| + | | **Sort** | 对元素进行升序排列 | ``list.Sort(); | ||
| + | | **Reverse** | 反转列表中元素的顺序 | ``list.Reverse(); | ||
| + | | **Remove** | 移除**第一个**匹配的特定对象 | ``list.Remove(5); | ||
| + | | **RemoveAt** | 移除**指定索引**处的元素 | ``list.RemoveAt(0); | ||
| + | | **RemoveRange**| 移除一定范围的元素 (起始索引, | ||
| + | | **Insert** | 在指定索引处插入一个元素 | ``list.Insert(1, | ||
| + | | **InsertRange**| 在指定索引处插入一个集合 | ``list.InsertRange(1, | ||
| + | |||
| + | **逻辑示例:安全添加** | ||
| + | <code csharp> | ||
| + | if (!list.Contains(5)) // 如果列表中没有 5 | ||
| + | { | ||
| + | list.Add(5); | ||
| + | } | ||
| + | else | ||
| + | { | ||
| + | // MessageBox.Show(" | ||
| + | Console.WriteLine(" | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ==== 1.4 遍历 List ==== | ||
| + | |||
| + | **方式 A:foreach 循环 (推荐)** | ||
| + | <code csharp> | ||
| + | List< | ||
| + | |||
| + | // 假设在 WinForms 中有一个 listBox1 | ||
| + | foreach (string item in list_data) | ||
| + | { | ||
| + | // listBox1.Items.Add(item); | ||
| + | Console.WriteLine(item); | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ==== 1.5 实战:计算平均值 ==== | ||
| + | |||
| + | <code csharp> | ||
| + | static void Main(string[] args) | ||
| + | { | ||
| + | var list = new List< | ||
| + | list.Add(8); | ||
| + | list.Add(2); | ||
| + | list.Add(3); | ||
| + | |||
| + | double avg = CalculateAverage(list); | ||
| + | Console.WriteLine(" | ||
| + | } | ||
| + | |||
| + | static double CalculateAverage(List< | ||
| + | { | ||
| + | double sum = 0; | ||
| + | | ||
| + | foreach (var item in kar) | ||
| + | { | ||
| + | sum = sum + item; | ||
| + | } | ||
| + | | ||
| + | // 注意:kar.Count 是 int,sum 是 double,除法结果为 double | ||
| + | if (kar.Count == 0) return 0; | ||
| + | return sum / kar.Count; | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ===== 2. ArrayList (动态数组 - 旧版) ===== | ||
| + | |||
| + | ``ArrayList`` 属于 ``System.Collections`` 命名空间。它是非泛型的,可以存储任意类型的元素(混合存储),但在现代开发中**不推荐使用**,因为它存在装箱拆箱的性能损耗且类型不安全。 | ||
| + | |||
| + | ==== 2.1 创建对象 ==== | ||
| + | |||
| + | <code csharp> | ||
| + | using System.Collections; | ||
| + | |||
| + | // 1. 创建空对象 | ||
| + | ArrayList listdd = new ArrayList(); | ||
| + | listdd.Add(" | ||
| + | listdd.Add(123); | ||
| + | |||
| + | // 2. 使用构造函数从现有数组创建 | ||
| + | int[] reey = new int[] { 1, 2, 3, 4, 5, 6 }; | ||
| + | ArrayList list = new ArrayList(reey); | ||
| + | </ | ||
| + | |||
| + | ==== 2.2 属性与方法 ==== | ||
| + | 用法与 ``List< | ||
| + | * ``Add(object value)`` | ||
| + | * ``Insert(int index, object value)`` | ||
| + | * ``Remove(object obj)`` | ||
| + | |||
| + | ===== 3. Hashtable (哈希表 - 旧版) ===== | ||
| + | |||
| + | ``Hashtable`` 用于存储**键值对 (Key-Value)**。它也是非泛型的,Key 和 Value 都是 ``object`` 类型。 | ||
| + | |||
| + | ==== 3.1 定义与添加 ==== | ||
| + | |||
| + | <code csharp> | ||
| + | Hashtable HaXi = new Hashtable(); | ||
| + | |||
| + | // 方式 1:使用 Add 方法 | ||
| + | HaXi.Add(1, 2); | ||
| + | HaXi.Add(2, 2.56); | ||
| + | HaXi.Add(3, false); | ||
| + | HaXi.Add(4, " | ||
| + | HaXi.Add(" | ||
| + | |||
| + | // 方式 2:使用索引器 (如果 Key 不存在则添加,存在则替换/ | ||
| + | HaXi[7] = 2.56; | ||
| + | HaXi[1] = 99; // 将 Key 为 1 的值更新为 99 | ||
| + | </ | ||
| + | |||
| + | ==== 3.2 常用操作 ==== | ||
| + | |||
| + | <code csharp> | ||
| + | // 移除 | ||
| + | HaXi.Remove(6); | ||
| + | |||
| + | // 判断 Key 是否存在 | ||
| + | if (!HaXi.ContainsKey(2)) | ||
| + | { | ||
| + | HaXi[2] = 9888; | ||
| + | } | ||
| + | |||
| + | // 判断 Value 是否存在 | ||
| + | bool hasValue = HaXi.ContainsValue(" | ||
| + | |||
| + | // 清空 | ||
| + | HaXi.Clear(); | ||
| + | </ | ||
| + | |||
| + | ==== 3.3 遍历 Hashtable ==== | ||
| + | |||
| + | 由于 Hashtable 是无序的,通常遍历 ``Keys`` 或 ``Values``,或者遍历 ``DictionaryEntry``。 | ||
| + | |||
| + | <code csharp> | ||
| + | // 遍历所有的 Key | ||
| + | foreach (var key in HaXi.Keys) | ||
| + | { | ||
| + | // 通过 Key 获取 Value | ||
| + | string content = "Key: " + key + " Value: " + HaXi[key]; | ||
| + | Console.WriteLine(content); | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ==== 3.4 数组转 Hashtable ==== | ||
| + | <code csharp> | ||
| + | int[] reey = new int[] { 1, 2, 3, 4, 5, 6 }; | ||
| + | Hashtable haxi = new Hashtable(); | ||
| + | |||
| + | // 将数组索引作为 Key,数组元素作为 Value | ||
| + | for (int i = 0; i < reey.Length; | ||
| + | { | ||
| + | haxi[i] = reey[i]; | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ===== 4. Dictionary< | ||
| + | |||
| + | ``Dictionary`` 是现代 C# 开发中存储键值对的首选。它比 Hashtable 更快、更安全。 | ||
| + | |||
| + | ==== 4.1 定义与初始化 ==== | ||
| + | |||
| + | <code csharp> | ||
| + | // 键是 int,值是 string | ||
| + | Dictionary< | ||
| + | |||
| + | // 初始化器语法 | ||
| + | var dict2 = new Dictionary< | ||
| + | { | ||
| + | { 1, " | ||
| + | { 2, " | ||
| + | }; | ||
| + | </ | ||
| + | |||
| + | ==== 4.2 增删改查 ==== | ||
| + | |||
| + | <code csharp> | ||
| + | // 1. 添加 (Add 方法如果 Key 已存在会报错) | ||
| + | dict.Add(3, " | ||
| + | |||
| + | // 2. 更新/ | ||
| + | dict[1] = "New Value"; | ||
| + | |||
| + | // 3. 删除 | ||
| + | dict.Remove(1); | ||
| + | dict.Clear(); | ||
| + | |||
| + | // 4. 安全查找 (重要!) | ||
| + | // 直接访问 dict[99] 如果 Key 不存在会抛出异常 | ||
| + | if (dict.ContainsKey(1)) | ||
| + | { | ||
| + | Console.WriteLine(dict[1]); | ||
| + | } | ||
| + | |||
| + | // 推荐:TryGetValue (尝试获取,返回 bool,值存入 out 参数) | ||
| + | string value; | ||
| + | if (dict.TryGetValue(1, | ||
| + | { | ||
| + | Console.WriteLine(" | ||
| + | } | ||
| + | else | ||
| + | { | ||
| + | Console.WriteLine(" | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ==== 4.3 遍历 Dictionary ==== | ||
| + | |||
| + | <code csharp> | ||
| + | // 1. 遍历键值对 (KeyValuePair) | ||
| + | foreach (KeyValuePair< | ||
| + | { | ||
| + | Console.WriteLine(" | ||
| + | } | ||
| + | |||
| + | // 2. 仅遍历键 | ||
| + | foreach (int key in dict.Keys) { /*...*/ } | ||
| + | |||
| + | // 3. 仅遍历值 | ||
| + | foreach (string val in dict.Values) { /*...*/ } | ||
| + | </ | ||
| + | |||
| + | ===== 5. 对比与总结 ===== | ||
| + | |||
| + | ==== 5.1 Hashtable vs Dictionary ==== | ||
| + | |||
| + | ^ 特性 ^ Hashtable ^ Dictionary< | ||
| + | | **类型安全** | **低** (非泛型,存取需类型转换) | **高** (泛型,编译时检查类型) | | ||
| + | | **性能** | **较差** (涉及装箱拆箱) | **优异** (无装箱,且无需同步开销) | | ||
| + | | **线程安全** | **是** (内部支持多线程同步,较慢) | **否** (默认非线程安全,需手动锁) | | ||
| + | | **命名空间** | ``System.Collections`` | ``System.Collections.Generic`` | | ||
| + | | **推荐场景** | 维护旧遗留代码 | **现代 C# 开发首选** | | ||
| + | |||
| + | ==== 5.2 扩展:ConcurrentDictionary ==== | ||
| + | |||
| + | 如果在**多线程**环境下需要频繁操作字典,推荐使用 ``ConcurrentDictionary``。 | ||
| + | |||
| + | * **命名空间**: | ||
| + | * **特点**: 它是线程安全的字典实现,不需要手动加锁 (lock),性能优于手动锁定的 Dictionary。 | ||
| + | |||
| + | <code csharp> | ||
| + | using System.Collections.Concurrent; | ||
| + | |||
| + | ConcurrentDictionary< | ||
| + | conDict.TryAdd(1, | ||
| + | </ | ||