首页 / C# 入门教程 / 调试入门

C# 入门教程

调试入门

本教程共 100 篇 · 第 6 篇 · 更新于 2026-07-31 · 约 9 分钟阅读

C#C# 入门教程调试Debug排错

6. 调试入门

本节目标:当程序出错或结果不对时,能用断点、单步和监视窗口定位问题,并看懂命令行报错。

写代码不可能一次写对。真正拉开差距的,不是”不写错”,而是”写错了能多快找出来”。这套找错的能力,叫调试(debug)。

什么是调试

调试就是让程序”慢动作重放”,你在一旁观察每一步的变量值,看它从哪一步开始偏离预期。与其靠眼睛盯代码瞎猜,不如让工具帮你把运行过程摊开看。

断点(breakpoint)

断点(breakpoint)是你在某行代码上打的”暂停标记”。程序跑到这一行会停下来,等你发话。

在 VS / VS Code 里,点行号左侧的空白处就能加断点(或按 F9)。停下来后,你可以:

  1. 查看当前每个变量的值。
  2. 决定是继续往下走,还是一行一行走。
  3. 修改某个变量再继续,观察影响。
Tip

断点不是越多越好。先在你”怀疑出问题”的那段附近打一个,跑起来看现场,比满屏红点高效得多。

单步执行

程序暂停后,常用三种”走法”:

  • 逐过程(Step Over):执行当前行,停到下一行。最常用。
  • 逐语句(Step Into):若当前行调用了别的方法,就钻进那个方法内部。想看细节时用。
  • 跳出(Step Out):从当前方法里一口气跑完,回到调用它的地方。

配合断点,你可以把一段可疑逻辑”逐帧”看完,哪一步算错了一目了然。

监视窗口与即时窗口

  • 监视窗口(Watch):你指定要盯哪些变量,窗口实时显示它们的值。适合观察某个值在循环里怎么变。
  • 即时窗口(Immediate):暂停时直接敲表达式,当场算给你看,比如输入 a + b 看结果。相当于给运行中的程序开了个计算器。
Note

这两个窗口在 VS / VS Code 的”调试”面板里都能找到。初学不必全用,先把”断点 + 逐过程”练熟,已经能解决大部分问题。

命令行运行与读报错

不是每次都方便开图形界面。用 dotnet run 时,如果代码有错,编译器或运行时会把错误信息打印在终端。学会读它,非常关键。

看一段故意写错的代码:

namespace CSharpDemo;

int x = 10;
int y = 0;
int result = x / y;   // 除以零
Console.WriteLine(result);

运行后,你会看到类似这样的报错:

未处理异常。System.DivideByZeroException: 尝试除以零。
   在 CSharpDemo.Program.Main(String[] args) ...
   在 ... 中

要点有三个:第一,异常类型 DivideByZeroException 直接告诉你”除以零”;第二,出错的文件和行号帮你定位;第三,下面的**堆栈(stack trace)**显示是”谁调用了谁”一路到这里。

Tip

读报错先看第一行异常类型,再找自己写的文件名和行号。框架内部的调用栈可以忽略,重点永远是你自己的代码行。

常见错误类型速记

报错关键词含义典型原因
CS0103当前上下文不存在名称拼错变量名,或忘了声明
CS0029类型不兼容把 string 赋给 int 之类
DivideByZeroException除以零分母算出来是 0
NullReferenceException空引用用了没实例化的对象

CS 开头的是编译期错误,代码还没跑就被拦下;不带 CS 的是运行期异常,跑起来才炸。

用输出大法做简易调试

没有图形界面时,最朴素的调试就是在关键处打印变量:

int total = 0;
foreach (var n in new[] { 1, 2, 3 })
{
    total += n;
    Console.WriteLine($"当前 n={n}, total={total}"); // 观察每一步
}

看打印出的 total 是不是按你想的涨,就能判断循环逻辑对不对。这是”断点”出现前的古老办法,至今好用。

Note

临时调试打印记得事后清理,别留一地 Console.WriteLine 在生产代码里。正式排查还是优先用断点。

没有调试器时怎么自救

不是所有环境都有图形化调试器(比如服务器上、远程容器里)。这时”输出大法”和”缩小范围”是两条救命绳:

  1. 缩小范围:把可疑代码整段注释掉,逐段放开,定位是哪一段出问题。比盯着全文强猜高效十倍。
  2. 边界值测试:出错的循环,试试空集合、只有一个元素、极大值,往往能复现隐藏 bug。
  3. 二分注释:怀疑是某段逻辑,先注释一半,跑通了再在另一半里继续二分,很快锁定。

调试的本质是”用证据代替猜测”。无论工具有无,这个心态最关键。

Tip

养成一个习惯:改完一处,立刻跑一次验证,而不是改完十处再统一跑。改动越集中,出错越好定位。这是老手和新手在效率上最明显的分水岭。

调试不是丢脸的事

新手常觉得”总报错=我菜”。恰恰相反,能快速定位并修复错误,才是真能力。每一位资深工程师每天都在 debug。把报错当成程序在”用它的语言告诉你哪里不对”,心态就稳了。

常见疑问解答

问:没有图形界面就没法调试吗? 不是。命令行报错的异常类型 + 行号就是最强线索。再配合临时 Console.WriteLine 打印关键变量,能解决绝大多数问题。图形调试器是锦上添花,不是必需。

问:断点打了程序却没停? 确认你是以”调试模式”启动(VS 按 F5,而非 Ctrl+F5 直接运行)。Ctrl+F5 是不调试运行,断点不会生效。另外代码若被优化或没编译,断点会显示空心。

问:为什么有时报错在框架内部而非我的代码? 那是你调用了某个库方法、由它内部炸开。看堆栈时往上找第一个你自己的文件名和行号,那才是问题源头。框架代码可以忽略。

要点速记

  • 调试 = 让程序慢下来给你看:断点暂停、单步推进。
  • 监视窗口盯变量,即时窗口当场算表达式。
  • 读报错先看异常类型,再找自己的文件名与行号。
  • CS 开头是编译期错误,其余多为运行期异常。

小结与下一步

调试的核心心法是”让程序慢下来给你看”:断点暂停、单步推进、监视盯值、即时验算。命令行报错也别怕,异常类型加行号就是你最好的线索。

下一章我们跳到语言层面,看看 C# 这一年一发的版本节奏,以及为什么本教程锁死 C# 14 / .NET 10。