第一个 C# 程序(顶级语句)
本教程共 100 篇 · 第 3 篇 · 更新于 2026-07-31 · 约 8 分钟阅读
3. 第一个 C# 程序(顶级语句)
本节目标:写出并跑通你的第一行 C# 代码,理解顶级语句(top-level statements)的写法与程序的编译运行流程。
终于要写代码了。这一章你会见到 C# 最简单的”Hello, World!”,并弄明白它为什么能跑起来。别小看这几行,它藏着现代 C# 最重要的一个语法设计:顶级语句。
用顶级语句写第一行代码
在上一章建好的 HelloWorld 项目里,打开 Program.cs,把内容改成这样:
Console.WriteLine("你好,世界!");
就这一行。保存,回到命令行执行:
dotnet run
屏幕会打印出 你好,世界!。恭喜,你的第一个 C# 程序跑起来了。
注意看:这里没有 namespace、class、static void Main 这些外壳。从 C# 9 起,你可以直接把可执行语句写在文件顶层,这叫顶级语句(top-level statements)。编译器会自动帮你包一层 Main 方法。
Note顶级语句不是”少了什么”,而是编译器替你省掉了样板代码(boilerplate)。初学阶段,它让你把注意力放在逻辑上,而不是结构上。等以后见到传统写法,你会一眼认出它们本质相同。
Console.WriteLine 是什么
Console 是 .NET 基础类库里负责”控制台输入输出”的类。WriteLine 是它的一个方法(method),意思是”写一行”——把括号里的文字输出到屏幕,并自动换行。
你可以连续输出多行:
Console.WriteLine("第一行");
Console.WriteLine("第二行");
Console.WriteLine("输出的内容是:" + 42);
第三行展示了最简单的拼接:用加号把文字和数字连起来。后面章节会学更优雅的写法(字符串插值)。
Tip对应地,
Console.ReadLine()用来从键盘读入一行文字。初学练习时,常在程序末尾加一句Console.ReadLine();,防止在某些环境下窗口一闪而过。本教程的示例大多不需要它。还有Console.Write(不换行)、Console.ReadKey(读一个键)等,按需取用。
读入用户输入
把上面那段改成能互动的小程序,感受一下”输入—输出”:
Console.WriteLine("请输入你的名字:");
string name = Console.ReadLine()!;
Console.WriteLine($"你好,{name}!");
这里 Console.ReadLine() 读进你敲的文字,存进变量 name;第二行用 $ 把变量塞进字符串里打印。那个 ! 是”我保证这不是空”的标记(叫空免除运算符,null-forgiving operator),先照写,后面讲可空类型时再细说。
程序是怎么编译运行的
你敲下 dotnet run,背后其实发生了三步:
- 还原(restore):确认项目依赖的库都就绪。
- 编译(build):C# 编译器把源代码翻译成中间语言(IL,Intermediate Language),生成可执行的程序集。
- 运行(run):.NET 运行时用即时编译(JIT,Just-In-Time)把 IL 变成当前机器的原生指令并执行。
dotnet run 把这三步打包成一条命令,方便你边写边看结果。等程序写好后,也可以用 dotnet build 只编译、不运行。
Note中间语言(IL)是”半成品”代码:它跟具体电脑无关,所以同一份编译结果能在不同系统上由各自的运行时执行。这正是 .NET 跨平台的底层逻辑。
用一个厨房的比喻理解这套链路:你写的 C# 源码是”菜谱”,编译器把菜谱翻译成”标准料理卡”(IL,谁都能读的统一格式),运行时里的 JIT 则像现场厨师,按当前厨房(Windows/macOS/Linux)的灶具把料理卡做成能上桌的菜。所以你写一次,到处能”做”。
一个更完整的入门示例
把前面学的串起来,写一个会做加法的程序:
Console.WriteLine("输入第一个数字:");
int a = int.Parse(Console.ReadLine()!);
Console.WriteLine("输入第二个数字:");
int b = int.Parse(Console.ReadLine()!);
int sum = a + b;
Console.WriteLine($"{a} + {b} = {sum}");
int.Parse 负责把读到的文字变成整数;int 是整数类型。这些细节后面都会专门讲,现在你只要感受”代码能跟人互动”就够了。
Tip如果输入的不是数字,
int.Parse会报错。真实项目里要用更安全的int.TryParse,我们在类型转换那章再展开。现在先接受”练习时乖乖输数字”。
为什么用顶级语句而非 Main
老教程(包括很多网上 C# 9 以前的文章)都会让你写 class Program { static void Main() { ... } }。那套写法没错,但对新手噪音太大:你得先理解什么是类、什么是静态方法、什么是入口,才能写出第一行输出。本教程统一用顶级语句起步,把你挡在这些概念门外,先看到程序跑起来。
等你熟悉了,第 4 章会专门对比”Main 方法”和”顶级语句”的关系,届时你两种都看得懂,也能在需要组织大型项目时从容写回传统结构。
顶级语句背后的真相
你可能会疑惑:没有 Main,程序从哪开始?答案是——编译器帮你补了一个隐藏的 Main。用 dotnet build 编译后,查看生成的代码,你会看到顶层语句都被收进了一个 Program 类的 Main 方法里。
理解这一点很重要:顶级语句是”语法糖”(syntactic sugar),让你少写样板,但底层机制和传统写法一致。所以你学顶级语句,本质上也在学 Main,只是没看见外壳。
Note一个项目里只能有一处顶级语句。若你建了两个
.cs文件都写顶层语句,编译器会报错”只能有一个包含顶级语句的文件”。正常项目里,入口只放一个文件。
顶级语句的摆放顺序
用顶级语句时有一条铁律:可执行语句必须写在文件最前面,任何类/结构/命名空间的定义都得放在它们之后。换句话说,你不能先定义一个 class,又在它后面写一句顶层输出——编译器会认为”入口语句散落各处”而报错。
// ✅ 正确:先写顶层语句
Console.WriteLine("先跑这句");
// 类型定义必须放在所有顶层语句之后
class Helper
{
public static void Assist() => Console.WriteLine("后定义也没事");
}
这条规则初学很少踩到,但当你开始往入口文件里加类时,记住”语句在前,类型在后”就行。
再写一个:用循环打招呼
为了让你更踏实,这里给一个带循环的小例子,体会”重复做事”:
for (int i = 1; i <= 3; i++)
{
Console.WriteLine($"第 {i} 次问候:你好!");
}
for 是循环(后面第 19 章细讲),这里你只需看懂:它会把大括号里的输出重复三遍。从一行打印,到读写互动,再到重复执行——你已经摸到”程序能干活”的门槛了。
运行出错了怎么办
新手第一次 dotnet run 常遇两类问题:
- 报错说找不到
dotnet:回到第 2 章检查 SDK 安装与环境变量。 - 一堆红色错误指向你的代码:别慌,错误信息里通常带着行号。先看第一个错误,往往改好它,后面的连锁错误也消失。
遇到看不懂的报错,把关键那行贴给搜索引擎,八成能找到答案。调试(第 6 章)会更系统地带你读错误。
Warning每条 C# 语句结尾要写分号
;。漏写分号是最常见的”红一片”原因之一,编译器常把错误标在下一行,反而让人摸不着头脑。写一句、分号一句,养成肌肉记忆。
常见疑问解答
问:顶级语句是不是”不正规”的写法?
不是。它是 C# 9 起官方支持的正式语法,底层有完整的 Main。许多现代模板默认就用它。你学的不是”旁门左道”,而是主流写法。
问:为什么我的 dotnet run 很慢?
首次运行要还原依赖、编译,会慢几秒;之后增量编译快很多。如果每次都卡很久,检查项目是否放在网络盘或杀软扫描目录。
问:可以一行写多条语句吗? C# 用分号分隔语句,理论上可挤一行,但极不推荐。一行一件事,出错时好定位,读起来也轻松。
问:顶级语句里能写类吗? 能,但类的定义必须放在所有顶层语句之后(见”摆放顺序”一节)。绝大多数入门示例不需要在入口文件写类,类都放到别的文件里更清爽。
要点速记
- 顶级语句让程序省掉
Main外壳,专注逻辑。 Console.WriteLine输出一行,Console.ReadLine读入一行。dotnet run= 还原 + 编译 + 运行,三步合一。- 源码先编译成 IL,再由运行时 JIT 成原生指令。
- 顶层语句在前,类型定义在后;一个项目只能有一处顶级语句。
小结与下一步
你已跑通第一行 C#:用顶级语句省掉外壳,靠 Console.WriteLine 输出,靠 dotnet run 一键编译运行。记住”源码 → 编译成 IL → 运行时执行”这条链路,以及”语句在前、类型在后”的摆放规则。
下一章我们把镜头拉远,看看一个完整 C# 程序在结构上由哪些部分组成。