
简介这份《C#程序100实例》资源包面向C#初学者及有一定经验的开发者精选100个可运行实例帮助读者从基本语法到LINQ、异步编程等进阶主题逐步贯通C#实践技能无需深厚基础按顺序练习即可上手。内容涉及变量与数据类型、控制结构、类与对象、封装继承多态、异常处理、事件与委托、LINQ查询、文件I/O与异步编程等几乎涵盖日常开发常用知识点适合边看边练。资源包共含1370个文件以200个CS源码、166个EXE演示程序、126个PDB调试文件及SLN解决方案和各类资源文件为主压缩包仅3.49MB便于下载查阅目前已有126人学习。每个实例均提供可运行工程与界面资源部分还带有可执行文件读者可对照源码与运行结果快速理解代码意图也能直接修改扩展实例难度由浅入深。无论是完成课程作业、准备面试还是日常项目开发这套实例都能起到查漏补缺、快速上手的作用。 我至今还记得第一本 C# 入门书就是那本经典的《C# 程序 100 例》翻目录就能看到打印三角形、水仙花数、猜数字这些“老面孔”。现在回头看这些例子确实基础但对当时的我来说每写出一个都是一次小小的正反馈。这些年带过不少新人也面试过不少候选人发现一个很有意思的现象能把 100 个实例真正吃透的人后面做项目的底子普遍比只刷视频、不写代码的人扎实得多。这篇就围绕“C#程序100实例”这个话题把我学习、复现、改造这些实例的经验整理出来顺便聊聊如何把 100 例的学习成果真正迁移到实战项目里。适合刚接触 C# 的初学者以及想系统巩固基础、准备面试的开发者参考。1. 为什么“100个实例”依然是学习C#的最佳路径1.1 实例驱动学习的底层逻辑很多人学 C# 的第一反应是买一本语法书从头看看到类、继承、委托这些概念就犯困翻两章就放弃了。这不是专注力的问题而是大脑对抽象概念的消化路径不对。语法书把知识点当作一棵完整的树来铺开但初学者心里没有树干叶子再多也挂不上去。实例学习正好相反每个实例都是一个“需求场景”你带着“怎么才能跑出这个结果”的问题去看代码、查语法知识点是挂在场景上的记得住也用得活。一个实例就是一个最小反馈闭环写代码、编译、运行、出结果、满意或者报错然后立刻调整。这个闭环越短学习效率越高。100 个实例正好提供了足够多的闭环并且难度是阶梯式上升的一开始是数据类型、运算符、分支循环慢慢过渡到字符串处理、集合操作、文件读写再往后是面向对象、多线程、网络通信。每一层的例子都在帮你把前一层的知识“用熟”而不是仅仅“见过”。这个“用熟”的过程恰恰是程序员和“会背概念的人”之间最本质的差别。1.2 100个实例如何覆盖C#核心知识体系很多人以为 100 个实例就是 100 个小玩具各自独立学完就忘。但我重新梳理了一遍经典 100 例的目录发现它其实暗合了软件开发的一条完整知识链路阶段典型实例覆盖的知识点基础语法九九乘法表、闰年判断、水仙花数变量、表达式、分支、循环字符串与集合字符串截取、逆序输出、List/Dictionary 操作常用 API、引用类型、集合泛型面向对象学生类、银行账户、继承与多态演示类、对象、封装、继承、多态、接口文件与数据文本文件读写、INI 配置、序列化IO、流、编码、Json/XML多线程与网络多线程计数、Socket 聊天、异步下载Thread、Task、TCP/UDP、async/await综合项目学生管理系统、简单计算器、图书管理分层设计、事件驱动、UI 交互这个分布不是巧合。它是在用 100 个具体问题把 C# 开发者日常工作中最高频的知识点全部过了一遍。所以与其说 100 个实例是“练习册”不如说它是一张“能力地图”。把这张地图走完你就具备了独立阅读项目源码、接手小型业务模块的能力。很多人问“我学完 C# 基础后下一步该学什么”我的答案永远是先把这张地图走完再决定往哪个方向深入。2. 最值得精读的几类实例与实操要点2.1 基础语法与控制流实例别嫌简单细节才是分水岭打印三角形、九九乘法表这类实例很多初学者看一眼就跳过觉得太低级。我反而建议你在这些题上多停留一会儿。基础题的价值不在“做出来”而在“能写出几种解法”。比如打印倒三角形用三个循环嵌套可以用字符串构造加 PadLeft 也可以用 LINQ 的 Enumerable.Range 同样可以。多写几种实现你才能真正理解循环边界、字符串拼接和空间换时间这些底层逻辑。这些逻辑不会直接出现在面试题里但会渗透到你写的每一行业务代码中。另一个容易被忽略的是字符串截取和转换。搜索热词里就有“c#语言怎样截取字符串”这是真实项目里天天用到的东西。Substring、Split、IndexOf、Remove 这几个方法必须熟练尤其要注意 Substring 的边界条件截取位置加上长度一旦越界就抛 ArgumentOutOfRangeException。我见过不少线上事故就出在这一个小细节上。建议你在实例做完后专门写一个“按分隔符解析配置项”的小函数把空字符串、分隔符连续出现、末尾带分隔符这些边界情况都测一遍。测完你会发现真正出问题的从来不是语法而是你对数据形态的预判够不够全面。2.2 面向对象与集合类实例把代码写“活”面向对象类实例是 100 例里最值得反复咀嚼的部分。学生类、银行账户、形状面积计算这些题目表面上是练习类的定义实际上是在建立你对“封装、继承、多态”这三板斧的直觉。很多新手容易犯的毛病是一个类里塞满了方法所有字段都写成 public类之间强耦合。你在做实例的时候就要刻意练习哪些字段应该私有哪个行为应该抽象成接口父类和子类的关系是否真的成立这些决策能力跟语法无关跟设计意识有关只能靠一次次写、一次次改来积累。这里特别想提“引用类型参数”这个问题热词里也有。C# 的引用类型参数传递本质上传递的是“对象的引用副本”所以在方法内部修改对象的属性是生效的但重新赋值一个新的对象并不会影响外部变量。这个特点如果不通过实例去亲手验证看十遍书也容易搞混。我建议你在面向对象实例做完后专门写一个 Demo 对比一下class Person { public string Name; } void ChangeReference(Person p) { p.Name Tom; // 外部对象也变了 p new Person { Name Jerry }; // 外部对象不变 }分别用值类型、引用类型、ref 关键字、out 关键字传参打印方法内部和外部的变量值对比跑一遍就彻底明白了。集合类实例也一样List、Dictionary、HashSet 各有各的适用场景选择错误会直接影响性能。比如大量按唯一键查找的场景用 List 加 Find 是 O(n)换成 Dictionary 就是 O(1)。100 例里的集合题目虽然简单但你在完成时要有意识地标注“这个场景为什么用这种集合”养成这个习惯后面读框架源码会轻松很多。2.3 文件操作与序列化实例数据持久化的第一课100 例做到中段就会出现文件读写的题目。文本写入、二进制读写、目录遍历这些实例是理解“程序如何与硬盘上的数据交互”的起点。做这类实例时最容易踩的坑是编码问题。用 File.ReadAllText 默认可能按 UTF-8 解析碰到 GB2312 编码的老配置文件就乱码必须显式指定 Encoding.Default 或者 Encoding.GetEncoding(GB2312)。还有路径拼接别用字符串加法直接拼路径要用 Path.Combine否则在不同操作系统上的目录分隔符会让你欲哭无泪。搜索热词里有一条“c#获取压缩包里的文件数量”这算是一个典型的文件处理进阶题。用 System.IO.Compression.ZipFile 就能实现核心代码很短using (var archive ZipFile.OpenRead(backup.zip)) { int count archive.Entries.Count(e !e.FullName.EndsWith(/)); Console.WriteLine($文件数量: {count}); }但核心不在 API在于理解“流需要被释放”这个原则。文件流、压缩流、网络流这些都是非托管资源用完必须释放。你可以在实例里尝试三种写法不用 using、用 using、用 try-finally观察资源释放的时机这样才算真正吃透了 IO 的本质。这些基础打不牢后面做日志系统、做数据导入导出一定会被内存泄漏和文件占用问题折磨。2.4 多线程与异步实例从“卡死”到“流畅”多线程实例是很多初学者的分水岭。经典 100 例里的多线程题目一般比较简单比如开几个线程做计数、模拟售票系统。但就是这些简单题目里藏着一个大坑线程安全。两个线程同时修改同一个 int 变量结果可能不是你想的累加值这就是竞态条件。做实例的时候请你至少用三种方式解决它lock、Interlocked.Increment、ConcurrentBag 并发集合。对比一下不同方案的性能和代码复杂度你会对“并发控制”有很直观的认识。搜索热词里还有“c# 查询线程 并中止线程”这是很多人踩过坑的方向。Thread.Abort 在 .NET 里已经被标记为过时因为强制中止线程会让对象状态不一致甚至引起锁未释放导致死锁。当年我也写过 Thread.Abort 去停掉一个死循环的线程结果整个进程的 UI 直接假死。正确做法是使用协作式取消也就是 CancellationTokenSourcevar cts new CancellationTokenSource(); Task.Run(() { while (!cts.Token.IsCancellationRequested) { // 执行任务 } }, cts.Token); cts.Cancel(); // 请求取消线程优雅退出把取消令牌传给任务方法在循环体里检查 IsCancellationRequested优雅地退出。这个知识点虽然超过基础 100 例的范畴但值得你在学完多线程实例后立刻补上。很多“高并发”“异步”相关的面试题追根溯源都是在考你这两点线程安全怎么做协作式取消怎么用。3. 从实例走向实战如何把“100例”扩展成项目能力3.1 实例改造的三步法很多人学完 100 例做过的实例都删了感觉自己什么都没留下。我自己的经验是实例做完不是结束而是改造的开始。我管这个过程叫“三步法”第一步改参数比如把打印三角形的例子改成打印菱形、打印旋转 90 度的三角形这个阶段熟悉代码结构第二步改结构加一个用户输入、加一个循环条件、把硬编码的数据改成从配置文件读取第三步加功能比如把“学生类”升级成支持增删改查的“学生管理系统”这需要引入集合、文件持久化或者数据库。三步法听起来简单但很多人做不到因为“改别人的代码”和“自己写代码”是两种心理体验。我的建议是100 例里挑 20 个你最有感觉的实例每个都按三步法改造一遍遇到不会的技术点就查文档、断点调试。比如把“猜数字”实例改成带计分、难度选择、历史记录的小游戏你会被迫学到枚举、事件、文件存储这些新东西。这个过程实际就是一次小型的项目开发训练做完你会发现自己再看那些“项目实战”视频脑子里不再是“看不懂”而是“这个我也可以试着写一个”。3.2 WinForm 与上位机开发的扩展路径有相当一部分人学 C# 的目标是做上位机开发搜索热词里“c#上位机开发”出现频率很高。上位机本质上就是与硬件设备交互的桌面应用程序开发者一般用 WinForm 或 WPF 来做界面。100 例里的窗口程序实例通常只是按钮、文本框的简单交互但你可以顺着这个方向深入先做一个串口调试助手做完串口收发再做数据显示曲线然后接入 Modbus 协议最后加上数据记录到数据库。每一步的起点都可能是 100 例里的某个基础窗口程序但它已经变成了真正的项目。在扩展 WinForm 实例时有一个经常被问到的问题“C# 的 WinForm 如何制作安装包”。这确实是从开发到交付的关键一步。Visual Studio 里可以用 Installer Projects 扩展或者用 Inno Setup 这个免费工具。我的心得是安装包的重点不是“能装上”而是“装上之后能跑”。目标机器是什么系统、装没装对应版本的 .NET 运行时、程序要不要管理员权限、配置文件放到哪里这些都要在打包前想清楚。你可以在本机先用 Inno Setup 打一个最简单的包然后在没有开发环境的干净虚拟机上测一遍这个实验比看任何教程都有效。3.3 数据库交互与业务系统100例后的下一个台阶100 例的后期往往会有一两个“学生管理系统”这类涉及数据存储的实例但通常只是文件存储。真实项目中数据库才是主角。从文件存储迁移到数据库要学的核心是 ADO.NET 或 EF Core。我建议不要直接跳到 ORM先用 ADO.NET 写一遍原生的 Connection、Command、DataReader把连接字符串、SQL 注入、连接释放这些基本概念搞清楚再使用 EF Core 提升开发效率。连接数据库的“底层模型”一旦建立你遇到任何数据访问问题都能快速定位到是连接问题、SQL 问题还是映射问题。搜索热词里出现“c#支持达梦”这和国产数据库在很多项目里逐步普及的趋势有关。达梦数据库与 Oracle 使用习惯相近C# 可以通过达梦官网提供的 .NET 驱动或标准 ODBC 连接。实际项目中如果你把连接字符串封装在配置文件里并统一在仓储层做数据访问以后在 SQL Server、达梦、PostgreSQL 之间切换成本会非常低。这个经验也说明100 例给你的不是“某一种数据库的 API 记背”而是“程序与数据库如何交互”这个底层模型。底层模型通了换什么数据库都只是换驱动和连接串的问题。4. 学习路上高频报错与排查技巧4.1 命令行与环境变量类报错很多新人第一次认真写 C#是在终端里执行 dotnet build 或者 dotnet run这时候最常看到的报错就是“wmic 不是内部或外部命令也不是可运行的程序”或者“git”无法将“项识别为 cmdlet、函数、脚本文件或可运行程序的名称”。这类报错第一次看到很慌但实际上原因往往只有一个系统在 PATH 环境变量里找不到对应的可执行文件。排查思路其实很固定。先看命令是否真的存在比如在 CMD 里执行 where git如果能找到路径说明是当前终端会话的 PATH 没刷新重启终端即可如果 where 也找不到说明要么程序没安装要么安装目录没加入 PATH。还有 Git、Node、JDK 这类自带命令行的工具安装后如果不把 bin 目录加进 PATH同样会报“不是内部或外部命令”。另外要注意的是有些工具要求重启 IDE 才能重新加载环境变量最常见的就是 VS Code 装完插件或改完 PATH 后要么重启编辑器要么开启一个新终端窗口否则环境变量不会自动生效。这类问题本身不难但很消耗新手耐心我把它们放在前面说就是希望大家遇到时别慌。4.2 C# 编译运行时的经典异常实例做得多了异常也是一个个见的。搜索热词里有一个很典型的C# 调用 C/C DLL 时报 System.AccessViolationException:“Attempted to read or write protected memory”。这个异常的本质是内存访问越界在调用非托管代码时尤其常见。常见原因包括DLL 的函数签名与 C# 声明不一致比如 C 语言用的是 int*而 C# 声明成了 int结构体布局不匹配需要加上 StructLayout(LayoutKind.Sequential)还有调用约定不一致C 默认是 CdeclWin32 API 是 StdCall用错会造成堆栈不平衡。遇到这类问题我的排查顺序是先用 DllImport 参数里的 CallingConvention 逐一尝试 Cdecl 和 StdCall然后打印 Marshal.SizeOf 检查结构体大小是否符合预期最后用 try-catch 包住调用把异常堆栈记录下来。如果项目允许还可以用 SafeHandle 替代 IntPtr 来管理非托管资源减少内存泄漏的风险。这个异常不是 100 例基础实例会直接教的但当你开始把基础实例向上位机、硬件交互方向扩展时几乎必然遇到。另一个常见异常是程序报“文件正由另一进程使用因此该进程无法访问此文件”。这通常是因为文件流没释放或者多个线程同时写入同一个文件。解决办法就是在代码里保证 using 块覆盖文件的所有读写操作其次考虑用 lock 或者队列来串行化写入。这些小坑积累多了你对各种异常的“体感”会越来越准确遇到新报错也不会慌而是会想“这个可能又是资源释放或者生命周期的问题”。4.3 一个通用的排查方法论排查报错这件事我建议大家把它当成一门基本功来刻意练习。我的固定套路是五步第一步完整复现。很多人报错只给一句“运行不了”没有报错日志、没有操作步骤这种信息等于零。你至少要自己能把报错稳定地复现出来。第二步分段定位。把程序分成输入、处理、输出三段用断点或者 Console.WriteLine 逐段确认哪一段出了问题。第三步精准搜索。把异常信息里最核心的几个词复制到搜索引擎注意删掉具体路径和变量名只保留异常类型和关键词。第四步小步修复。一次只改一个变量或一个方法改完重新编译运行不要一次性做多个改动。第五步验证回归。修复一个 bug 后把相关场景都测一遍确认没有引入新问题。这套方法论看起来很朴素但真正每次都照着做的人并不多。很多人一遇到报错就慌或者凭感觉乱改最后浪费半天时间。你从 100 例开始就可以训练这套流程每次实例跑不出来先深呼吸按五步走一遍。练到第 50 个实例的时候你排查问题的速度会比周围的人快一倍以上。这个过程没什么捷径就是一遍遍在现场里“泡”出来的。最后说一点个人的体会。C# 程序 100 实例这套东西任何时候回看都不觉得过时。它能帮你建立的基础比市面上很多花哨的框架教程都扎实。做完这些实例之后你会发现真正重要的不是记住了多少 API而是你养成了“看到需求能拆解成代码步骤”的习惯。这个习惯一旦建立学 WPF、学 ASP.NET Core、学上位机、学云原生都只是时间问题。如果你正在刷这 100 个实例别贪快每个例子都亲手敲一遍、改造一遍跑不通就断点调试。这段略显枯燥的时光恰恰是后面解决问题的底气所在。本文还有配套的精品资源点击获取