C#程序100实例:从基础语法到实战项目迁移的完整指南
2026/9/3 18:11:36 网站建设 项目流程

简介:这份《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 直接假死。正确做法是使用协作式取消,也就是 CancellationTokenSource:

var 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 默认是 Cdecl,Win32 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 个实例,别贪快,每个例子都亲手敲一遍、改造一遍,跑不通就断点调试。这段略显枯燥的时光,恰恰是后面解决问题的底气所在。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询