C# 从集合、泛型、异常到 IO、多线程全套入门笔记
摘要本文整合 C# 基础进阶五大核心模块非泛型 / 泛型集合、泛型原理与约束、异常处理机制、文件 IO 流操作、进程与多线程同步配套完整可运行代码区分新旧容器优劣总结开发避坑点适合零基础入门、面试突击复习。 标签C#; .NET; 集合泛型多线程IO 流异常处理 分类后端开发 / C# 桌面开发前言初学 C# 时很容易混淆ArrayList和List、分不清栈 / 队列使用场景、写文件忘记释放资源、多线程并发出现数据错乱。本文结合课堂全套笔记把集合容器、泛型、异常、IO 文件、多线程五大高频知识点一次性梳理清楚所有案例均可直接复制运行同时标注生产环境推荐写法与淘汰 API。一、集合容器线性容器 键值容器1.1 非泛型容器System.Collections新项目不推荐1.1.1 ArrayList 动态数组本质是object[]可存任意类型存在装箱拆箱损耗无类型校验。核心特性容量自动扩容默认初始容量 16支持Add()尾部添加、Insert(index,obj)指定位置插入删除Clear()清空、Remove(元素)删首个匹配、RemoveAt(索引)、RemoveRange(起始,数量)查询Contains()判断存在、IndexOf()获取索引属性Count实际元素数 /Capacity总容量。示例代码csharp运行using System; using System.Collections; class TestArrayList { static void Main() { ArrayList arr new ArrayList(); arr.Add(10); arr.Add(测试字符串); arr.Add(true); arr.Insert(1, 999); // 索引1插入999 arr.Remove(测试字符串); // 删除指定元素 arr.RemoveAt(0); // 删除索引0 Console.WriteLine(arr.Contains(true)); // true // 遍历 foreach (var item in arr) { Console.WriteLine(item); } } }缺点混合类型存储取值强制转换极易报错性能差新项目一律用ListT替代。1.1.2 Queue 队列FIFO 先进先出场景消息队列、任务排队、打印队列。入队Enqueue(obj)出队取出并删除Dequeue()查看队首不删除Peek()统计Countcsharp运行Queue queue new Queue(); queue.Enqueue(消息1); queue.Enqueue(消息2); Console.WriteLine(queue.Peek()); // 消息1 Console.WriteLine(queue.Dequeue()); // 消息1队列仅剩消息21.1.3 Stack 栈LIFO 后进先出场景撤销操作、递归回溯、表达式求值。入栈Push(obj)出栈Pop()查看栈顶Peek()csharp运行Stack stack new Stack(); stack.Push(页面A); stack.Push(页面B); Console.WriteLine(stack.Pop()); // 页面B1.1.4 Hashtable 哈希键值对键唯一存储DictionaryEntry同样 object 装箱淘汰方案DictionaryTKey,TValuecsharp运行Hashtable ht new Hashtable(); ht.Add(id, 1001); ht[name] 张三; // 赋值键存在则覆盖 Console.WriteLine(ht.ContainsKey(id)); // 遍历键值对 foreach (DictionaryEntry kv in ht) { Console.WriteLine(${kv.Key}:{kv.Value}); }1.1.5 SortedList 自动排序键值容器自动按照 key 升序同时支持索引访问键访问双模式不允许重复 key。csharp运行SortedList sl new SortedList(); sl.Add(3, C); sl.Add(1, A); sl.Add(2, B); // 自动排序输出 1:A 2:B 3:C1.2 泛型容器System.Collections.Generic生产首选1.2.1 ListT 泛型动态数组替代 ArrayList强类型约束无装箱拆箱编译期类型检查方法与 ArrayList 完全对齐。csharp运行// 集合初始化器 Listint numList new Listint() { 1,2,3,4 }; numList.Add(5); numList.Insert(0,0); // 存储自定义实体 class Student { public int Id { get; set; } public string Name { get; set; } } ListStudent stus new ListStudent() { new Student{Id1001,Name小明} };1.2.2 DictionaryTKey,TValue 泛型字典替代 Hashtable核心优势O (1) 键查找推荐TryGetValue安全取值避免键不存在抛异常。csharp运行Dictionarystring,int ageDic new Dictionarystring,int(); ageDic[小明] 18; ageDic.Add(小红,17); // 安全取值推荐 if(ageDic.TryGetValue(小明,out int age)) { Console.WriteLine(age); } // 三种遍历 foreach(var kv in ageDic){} // 键值对 foreach(var k in ageDic.Keys){} // 仅键 foreach(var v in ageDic.Values){} // 仅值1.2.3 QueueT / StackT 泛型栈队列用法同非泛型仅增加类型约束杜绝类型混乱。csharp运行Queuestring msgQueue new Queuestring(); Stackint numStack new Stackint();1.3 容器选型对照表表格容器存储结构特性适用场景推荐度ArrayListobject 数组任意类型、装箱老旧维护项目❌淘汰ListTT 数组强类型、索引、扩容列表、批量数据✅首选QueueT循环数组FIFO 先进先出任务队列、消息✅常用StackT数组LIFO 后进先出撤销、递归✅常用Hashtable哈希表object 键值、装箱老旧项目❌淘汰Dictionary泛型哈希强类型、极速查键缓存、映射关系✅首选SortedList有序数组按键自动排序需要有序键值⭐按需使用二、泛型解决装箱拆箱与类型复用2.1 装箱 拆箱底层原理装箱值类型 → object 引用类型堆分配性能损耗拆箱object → 原始值类型强制转换csharp运行// 装箱 int a 10; object obj a; // 拆箱 int b (int)obj;非泛型容器存储值类型时会频繁装箱大量循环下性能断崖下跌泛型从根源解决该问题。2.2 泛型基础泛型方法 / 泛型类泛型将类型参数延迟到调用时指定编译器 JIT 会为每种 T 生成专属代码无装箱。泛型方法示例csharp运行// T为类型占位符 public static void ShowT(T data) { Console.WriteLine($数据{data}类型{typeof(T)}); } // 调用自动推导类型 Show(123); Show(测试文本); Show(DateTime.Now);泛型类示例csharp运行class MyContainerT { private T _data; public void Set(T val) _data val; public T Get() _data; } // 使用 MyContainerstring strBox new MyContainerstring(); strBox.Set(泛型测试);2.3 五大泛型约束 where通过where限制 T 的类型范围访问类型自有属性 / 方法where T : struct必须是值类型where T : class必须是引用类型where T : new()必须有无参公共构造函数放最后where T : 基类必须继承该类where T : 接口必须实现该接口csharp运行// 多重约束new()写末尾 public static void PrintUserT(T user) where T : People, ISay, new() { user.SayHi(); } class People { public int Id; } interface ISay { void SayHi(); }三、异常处理try-catch-finally 自定义异常3.1 常见系统异常IndexOutOfRangeException数组 / 集合下标越界NullReferenceException空对象调用成员DivideByZeroException除零错误IOException文件读写失败ArgumentException参数非法3.2 核心语法try-catch-finallytry存放可能报错代码catch捕获对应异常精准异常写在前Exception 兜底finally无论是否报错一定会执行用于释放资源文件、网络连接csharp运行static void ReadFileDemo() { FileStream fs null; try { fs new FileStream(test.txt, FileMode.Open); byte[] buf new byte[1024]; fs.Read(buf,0,buf.Length); } catch(FileNotFoundException ex) { Console.WriteLine(文件不存在ex.Message); } catch(Exception ex) { Console.WriteLine(未知错误ex); } finally { // 释放流资源 fs?.Close(); fs?.Dispose(); } }3.3 using 语法糖替代手动释放资源实现IDisposable接口的对象文件流、数据库连接可用using编译自动生成try-finally释放资源简化代码csharp运行// 等价上方finally释放逻辑 using(FileStream fs new FileStream(test.txt,FileMode.Open)) { byte[] buf new byte[1024]; fs.Read(buf,0,buf.Length); }3.4 throw 三种写法避坑throw ex;❌ 不推荐重置异常堆栈丢失原始报错行throw;✅ 推荐保留完整异常栈throw new Exception(提示,ex);✅ 包装异常形成异常链InnerExceptioncsharp运行try { int a 1 / 0; } catch(DivideByZeroException ex) { // 包装内部异常便于日志排查 throw new BusinessException(计算出错, ex); }3.5 自定义异常业务场景区分系统异常继承Exceptioncsharp运行public class BusinessException : Exception { public BusinessException(){} public BusinessException(string msg):base(msg){} public BusinessException(string msg,Exception inner):base(msg,inner){} } // 抛出自定义异常 throw new BusinessException(用户余额不足);四、IO 文件与流操作System.IO4.1 静态工具类Path / File / DirectoryPath路径处理不操作物理文件csharp运行string path C:\Desktop\demo.txt; Console.WriteLine(Path.GetFileName(path)); // demo.txt Console.WriteLine(Path.GetExtension(path)); // .txt Console.WriteLine(Path.GetDirectoryName(path)); // C:\Desktop Console.WriteLine(Path.Combine(C:\Desktop,a.txt)); // 拼接路径File文件静态读写小文件首选csharp运行// 一次性读取全部文本 string text File.ReadAllText(demo.txt,Encoding.UTF8); // 按行读取 string[] lines File.ReadAllLines(demo.txt); // 覆盖写入 File.WriteAllText(demo.txt,写入内容); // 追加写入 File.AppendAllText(demo.txt,追加文字); // 二进制读写图片、视频 byte[] data File.ReadAllBytes(1.jpg); File.WriteAllBytes(copy.jpg,data);Directory文件夹操作csharp运行Directory.CreateDirectory(C:\test); // 创建文件夹 Directory.Delete(C:\test,true); // true递归删除所有子文件 bool hasFolder Directory.Exists(C:\test);4.2 流分类Stream 抽象基类FileStream字节流读写任何文件图片 / 视频 / 文本StreamReader/StreamWriter字符流专门处理文本自带编码BufferedStream缓冲流提升大文件读写性能MemoryStream内存流无磁盘 IO文本读写示例StreamReader/StreamWritercsharp运行// 读取 using(StreamReader sr new StreamReader(demo.txt,Encoding.UTF8)) { while(!sr.EndOfStream) { string line sr.ReadLine(); } } // 写入第二个参数true追加 using(StreamWriter sw new StreamWriter(demo.txt,true,Encoding.UTF8)) { sw.WriteLine(新增一行); }五、进程与多线程同步System.Threading5.1 Process 进程类启动程序 / 查看进程csharp运行// 打开记事本 Process.Start(notepad); // 遍历所有进程关闭Edge foreach(var p in Process.GetProcesses()) { if(p.ProcessName.ToLower() msedge) { p.Kill(); } }5.2 Thread 基础线程主线程Main方法线程子线程用于耗时操作文件、网络、计算无参 / 有参线程创建csharp运行// 无参线程 Thread t1 new Thread(DoWork); t1.Start(); // 带object参数线程 Thread t2 new Thread(DoParamWork); t2.Start(传入参数); static void DoWork() { Console.WriteLine(子线程执行); } static void DoParamWork(object arg) { Console.WriteLine(arg.ToString()); }常用线程方法Start()启动线程Sleep(毫秒)当前线程休眠Join()阻塞主线程等待子线程执行完毕IsBackgroundtrue后台线程程序退出自动销毁5.3 线程同步锁 lock解决资源竞争多线程同时修改同一变量会出现数据错乱用 lock 锁定临界资源csharp运行class AppleDemo { static int appleCount 10; // 私有静态锁对象禁止string、this、typeof static readonly object locker new object(); static void Main() { Thread t1 new Thread(EatApple); Thread t2 new Thread(EatApple); t1.Start(张三); t2.Start(李四); } static void EatApple(string name) { while(true) { lock(locker) { if(appleCount 0) break; appleCount--; Console.WriteLine(${name}吃苹果剩余{appleCount}); Thread.Sleep(500); } } } }lock 避坑不要锁字符串、不要锁实例 this推荐私有静态只读 object。5.4 Mutex 跨进程互斥锁用于限制程序单开多个 exe 互斥csharp运行bool newMutex; Mutex mutex new Mutex(true,SingleApp,out newMutex); if(!newMutex) { Console.WriteLine(程序已启动直接退出); return; }六、全套知识点总结集合选型新项目全部使用泛型ListT、DictionaryTKey,TValue摒弃 ArrayList、Hashtable栈队列按需选用StackT/QueueT。泛型核心消除装箱拆箱编译类型安全where约束拓展泛型能力。异常规范分层捕获异常优先使用throw保留堆栈资源必须用using释放。IO 操作小文件用 File 静态方法大文件使用带缓冲流文本用 StreamReader多媒体用 FileStream 字节流。多线程规范共享资源必须加 lock 同步区分前后台线程避免死锁。七、面试高频问答ArrayList 和 ListT区别 答ArrayList 存储 object装箱拆箱、无类型校验ListT泛型强类型无性能损耗编译报错提前拦截。Dictionary 查找速度为什么快 答底层哈希表通过哈希码定位平均 O (1) 查询效率。using 的底层原理 答实现 IDisposable 接口编译生成 try-finally 块自动调用 Dispose 释放非托管资源。多线程不加锁会出现什么问题 答共享变量读写错乱、数据脏读业务逻辑结果不符合预期。

相关新闻

小白嵌入式学习-使用stm32103c8t6

小白嵌入式学习-使用stm32103c8t6

按钮实验思路:使用推挽模式,对输入寄存器GPIO PA1存入01值(通过史密斯将高低电平转化为01)如果读取GOIO引脚PA1的数值为0(按钮按下,电路接地,输出0,反之输出1)Stm32读取到…

2026/10/15 21:22:15 阅读更多 →
2026百度网盘解析与直链下载全解析:pandownload+kdown极速提速方案实测

2026百度网盘解析与直链下载全解析:pandownload+kdown极速提速方案实测

PanDown - 网盘不限速下载工具PanDown是一款永久免费的网盘解析与多线程提速下载工具。坚持以用户体验作为核心,将加速进行到底!https://www.pandown.org/ 在日常处理大型文件、备份数据或获取资料时,数据传输效率直接影响着我们的工作与学习…

2026/10/15 21:22:16 阅读更多 →
GitHub私有仓库SSH访问配置全流程指南

GitHub私有仓库SSH访问配置全流程指南

1. GitHub 私有仓库SSH访问配置全流程指南作为开发者日常工作的刚需,SSH密钥访问GitHub私有仓库的配置看似简单,实际暗藏不少平台差异性和配置细节。我在为团队制定标准化操作流程时,发现即便是经验丰富的工程师,也常会在密钥权限…

2026/10/15 6:37:48 阅读更多 →

最新新闻

CTF新手题easychallenge:Python脚本加密与逆向思路全解析

CTF新手题easychallenge:Python脚本加密与逆向思路全解析

前两天在攻防世界的 CRYPTO 新手练习区刷题,刷到 easychallenge 这一道,名字起得特别诚实,但实战起来也不能说完全 easy。它不考复杂的数学公式,也不考高深的密码算法,更像是给你一段加密脚本,让你自己把它…

2026/10/15 21:22:32 阅读更多 →
ESP8266接OLED:从选型接线到点亮显示全教程

ESP8266接OLED:从选型接线到点亮显示全教程

你有没有过这种体验:ESP8266串口打印出来的数据堆了一屏,盯着串口监视器看得眼花缭乱,明明传感器读出了26.5℃,却没法让这个数字变成一眼能看懂的"画面"。我第一次做物联网小项目时就被这个问题卡了很久。后来接上一块0…

2026/10/15 21:22:32 阅读更多 →
嵌入式C++单链表实战:内存可控的类型擦除链表设计

嵌入式C++单链表实战:内存可控的类型擦除链表设计

1. 这不是教科书里的“单链表”,而是你明天就能抄进项目的实战结构 单链表——这三个字一出来,很多人脑子里立刻浮现出黑板上画的箭头、节点、next指针,还有老师念叨的“头结点不存数据”“遍历时间复杂度O(n)”……但现实里,我带…

2026/10/15 21:22:32 阅读更多 →
ESP8266驱动OLED屏入门:接线、配置与点亮指南

ESP8266驱动OLED屏入门:接线、配置与点亮指南

1. OLED屏与ESP8266的适配思路 手头正好有一块0.96寸的OLED屏,一直想做个小玩意儿,就顺手用ESP8266驱动了起来。先说结论:这对于入门嵌入式显示来说,是很典型也很有意思的组合——OLED功耗低、自发光、显示效果好,ESP8…

2026/10/15 21:22:32 阅读更多 →
ESP8266驱动OLED屏:从选型到点亮,玩转中文显示与动画

ESP8266驱动OLED屏:从选型到点亮,玩转中文显示与动画

做嵌入式小项目时,最烦的不是代码跑不起来,而是跑起来之后什么都看不见。传感器数据全堆在串口里,手机又懒得开,这时候给 ESP8266 配上一块 OLED 屏幕,整个项目立刻“活”了。这篇文章是 OLED 在 ESP8266 中应用系列的…

2026/10/15 21:22:32 阅读更多 →
YOLOv10【第十一章:生成式 AI 与自动标注篇·第1节】生成式 AI 如何赋能 YOLOv10:数据、标签、推理三条路线

YOLOv10【第十一章:生成式 AI 与自动标注篇·第1节】生成式 AI 如何赋能 YOLOv10:数据、标签、推理三条路线

🏆 本文收录于 《YOLOv10实战:从入门到深度优化》 专栏。 该专栏系统复现并深度梳理全网主流 YOLOv10 改进方法与工程实战案例,覆盖分类、目标检测、实例分割、多目标追踪、关键点检测、旋转目标检测等多个方向,坚持 持续更新 + 深度解析 + 工程验证。 专栏将围绕 YOLOv10…

2026/10/15 21:21:31 阅读更多 →

日新闻

Docker Compose 容器化部署 ChirpStack LoRaWAN 网络服务器实战

Docker Compose 容器化部署 ChirpStack LoRaWAN 网络服务器实战

1. 为什么选择容器化方式部署 LoRa 网络服务LoRa 物联网项目落地时,网络服务器是整个链路的核心枢纽。它负责接收网关上报的数据包、完成去重与解密、再把有效载荷分发给上层应用。早期大家习惯把网络服务器直接装在物理机上,依赖一堆系统库和特定版本的…

2026/10/15 0:00:46 阅读更多 →
共享LLM服务下的跨模型自动扩缩容:Kubernetes实战与避坑指南

共享LLM服务下的跨模型自动扩缩容:Kubernetes实战与避坑指南

1. 共享推理服务里,扩缩容到底难在哪做过大模型推理服务部署的人,大概都经历过这样的场景:一个团队共用一套推理集群,A 业务跑的是 7B 的小模型,B 业务跑的是 72B 的大模型,C 业务白天流量高、晚上几乎归零…

2026/10/15 0:00:46 阅读更多 →
Systemd 启动阶段根文件系统只读之谜:fstab 与 remount-fs 服务深度解析

Systemd 启动阶段根文件系统只读之谜:fstab 与 remount-fs 服务深度解析

1. 引子:一次内核恐慌引发的追查先从一个真实场景说起。某次我给一台老旧的嵌入式设备折腾系统裁减,为了把启动时间压进两秒以内,我手贱地把一串自认为“没用”的 systemd 服务给 disable 了,其中就包括systemd-remount-fs.servic…

2026/10/15 0:00:46 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/15 16:18:54 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/15 19:41:51 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/15 13:48:15 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 0:14:36 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/14 22:45:47 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 9:49:14 阅读更多 →