csharp:集合

差别

这里会显示出您选择的修订版和当前版本之间的差别。

到此差别页面的链接

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

该主题尚不存在

您访问的页面并不存在。如果允许,您可以使用创建该页面按钮来创建它。