首页 / C# 入门教程 / C# 程序结构

C# 入门教程

C# 程序结构

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

C#C# 入门教程命名空间程序结构Main 方法

4. C# 程序结构

本节目标:看懂一个 C# 文件由哪些部分组成,理解命名空间、using 指令,并分清 Main 方法与顶级语句两种入口写法。

前几章我们用顶级语句”绕开”了程序的外壳。现在回过头把外壳拆开看:命名空间、using、类、Main 方法,各自是什么角色。理解了结构,你读别人的代码才不晕,自己写大一点的程序也知道东西该放哪。

一个”传统写法”的完整程序

先给出带完整结构的版本,方便对照:

namespace CSharpDemo;

class Program
{
    static void Main()
    {
        Console.WriteLine("你好,结构!");
    }
}

它和前面 Console.WriteLine(...) 一行版,跑出来效果完全一样。差别只在于:编译器替顶级语句生成的,正是这种带 Main 的结构。

命名空间(namespace)是什么

命名空间(namespace)是给代码”分文件夹”的机制。项目一大,难免有两个都叫 Student 的类——一个管学生信息,一个管奖学金。用命名空间隔开,就能并存且不冲突。

文件范围命名空间(file-scoped namespace)是 C# 10 引入的省事写法:一行 namespace CSharpDemo; 后面不跟花括号,整个文件都属于这个命名空间。这是本教程默认采用的风格。

Note

旧写法要用花括号把整个文件包起来:

namespace CSharpDemo
{
    class Program { }
}

两种等价,但文件范围写法更清爽,也更符合现代 C# 习惯。本教程统一用文件范围写法,只有专门讲命名空间的那一章(第 37 章)才展开对比。

不写命名空间会怎样

你也许想:那我不写 namespace 行不行?行,但代价是”类散落在全局命名空间”。小练习无所谓,项目一大就麻烦:

  • 两个同名类撞车时,编译器分不清你要哪个。
  • 别人用你的代码时,找不到清晰的归属,引用起来啰嗦。

所以约定是:普通类文件都写上 namespace,把类收进自己的”文件夹”。只有带顶级语句的入口文件例外——它本来就是程序起点,编译器默认把它放进全局命名空间,你不必(也不能)给它套命名空间。

using 指令:引入工具箱

你想用 Console,得先让编译器知道它在哪。Console 实际住在 System 这个命名空间里。传统上要写:

using System;

这就是 using 指令(using directive):告诉编译器”去这个命名空间里找类型”。不写的话,你就得写全名 System.Console.WriteLine(...),很啰嗦。

隐式全局 using(.NET 6+ 模板)

本教程前面所有示例,你都没写过 using System;,照样能用 Console。这是因为 .NET 6 起的默认模板开启了隐式全局 using(implicit global using):编译器自动帮你引入一批最常用命名空间,包括 SystemSystem.LinqSystem.Collections.Generic 等。

所以你能直接写 List<string>Consoleint.Parse,都不用手动 using。只有用到冷门命名空间时,才需要自己加一行 using

Tip

想看项目自动引入了哪些命名空间?打开项目里的 obj/Debug/.../项目名.GlobalUsings.g.cs 文件,里面列得清清楚楚。初学不必深究,知道”默认就有”即可。

类与方法:真正的执行体

class Program 定义了一个类(class)——C# 是面向对象语言,代码大多装在类里。怎么理解类?把它想成”图纸”:图纸本身不是房子,按图纸能造出很多栋一样的房子。类是图纸,new 出来的对象就是按图纸造出的那栋具体房子。

static void Main()入口方法(entry point),程序启动时从这里开始执行。拆开看每个词:

  • static:属于类本身,不需先 new 一个对象就能调用。
  • void:这个方法不返回任何值。
  • Main:固定名字,C# 约定它为程序入口。

一个方法(method)就像一台小机器:吃进参数(原料),干完活,吐出返回值(产品)或不吐。Main 是那台”启动整机”的机器。

Main 方法 vs 顶级语句

两种方式本质相同,选哪个看你场景:

写法适合特点
顶级语句小程序、脚本、教学示例无 class/Main 外壳,专注逻辑
传统 Main需要清晰组织多个类/方法的大型项目结构明确,便于扩展

顶级语句底层就是一段藏在背后的 Main。所以你学顶级语句时,其实已经在使用 Main 了,只是没看见。

Note

一个项目里要么用顶级语句,要么自己写 Main,不能两个都要。编译器规定:含顶级语句的文件,不能再有 Main 方法,也不能套在命名空间花括号里。

using 的另一种用法:静态导入

除了引入命名空间,还能直接导入某个类的静态成员,少写类名:

using static System.Console;

WriteLine("这样可以省掉 Console 前缀");

这种写法在小型示例里很方便,但大项目里为了可读性,通常还是写全 Console.WriteLine

using 的第三种用法:取别名

当两个不同的命名空间里出现同名类型,或名字太长想简写,可用 using 取别名(alias):

using Project = CSharpDemo.School.Student;

Project p = new();   // 等价于 CSharpDemo.School.Student

别名在”引入第三方库、名字撞车”时特别救命。初学不常见,但知道有这招,将来见到不慌。

一个文件能写多个类吗

能。C# 不要求”一个文件一个类”。你可以在一个 .cs 文件里写多个 class,只要它们不在同一个命名空间里撞名即可。不过约定俗成的做法是”一个文件放一个类”,且文件名和类名一致,方便查找。本教程为聚焦单点,示例常把相关类放一起,你实际项目里按”一文件一类”组织更清晰。

顶级语句能和命名空间共存吗

不能。含顶级语句的文件,编译器会把它当成”程序入口”,不允许再写命名空间声明或 Main 方法。所以:

  • 写顶级语句的入口文件:直接用顶层语句,不写 namespace
  • 写类库/普通类文件:用 namespace CSharpDemo; 组织。

本教程的入口示例走顶级语句,讲结构时再补命名空间外壳,两者不冲突,只是出现在不同文件里。

Tip

记住一句话:入口文件负责”跑”(顶级语句),其他文件负责”定义”(类、命名空间)。职责分开,项目越大越不乱。

一个带方法的类示例

把前面说的”类+方法”落在代码上,感受结构怎么搭:

namespace CSharpDemo;

class Calculator
{
    public int Add(int a, int b)
    {
        return a + b;
    }
}

// 在另一个文件或同文件的方法之外,可这样调用:
// var calc = new Calculator();
// int result = calc.Add(2, 3);

Calculator 是类,Add 是它对外提供的方法:接收两个整数参数,返回它们的和。public 表示”谁都能用”。这个骨架你以后会写无数遍。

常见疑问解答

问:不写 namespace 会出错吗? 顶级语句的入口文件可以不写,编译器默认放进全局命名空间。但普通类文件建议写 namespace,否则类会散落在全局,大项目易冲突。

问:using 写错位置会怎样? using 指令必须放在文件顶部(任何语句之前)。顶级语句文件里,把 using 写在代码最前面即可。放错位置编译器会直接报错,按提示挪到顶就行。

问:类和方法必须 public 吗? 入门示例为了简单常省略修饰符。实际项目里,对外暴露的用 public,内部用的用 private。可见性(第 29 章)是面向对象的护栏,初学先不纠结。

问:方法里能再写方法吗? 能,那叫”局部函数”(第 52 章会讲)。现在你只要知道:常规做法是把方法写在类里,而不是直接塞进 Main

要点速记

  • 文件范围命名空间 namespace X; 是 C# 10 的省事写法。
  • 隐式全局 using 免写常见 using 指令;using static 省类名,using 别名 解决重名。
  • 类像图纸、对象像按图造出的实物;方法吃参数、干活的机器。
  • 类承载逻辑,Main 或顶级语句是程序入口。
  • 顶级语句与 namespace/Main 不能同文件出现。

小结与下一步

现在你能看懂一段 C# 的骨架了:文件范围命名空间组织归属,隐式全局 using 让你免写常见引用,类与方法承载真正逻辑,而 Main 或顶级语句是起点。这些结构像房子的框架,接下来我们要往里填”内容”——从注释和命名规范开始。

下一章讲注释与代码约定,好代码首先要让别人(包括未来的你)看得懂。