☰
C# 预处理器指令详解
2026/10/9 15:52:13 网站建设 项目流程

C#预处理器指令(Preprocessor Directives)是以#开头的特殊命令,它们不会生成 IL(中间语言)代码,而是在编译之前由编译器处理,用来控制代码是否参与编译、定义符号、输出警告等。

与 C/C++ 不同,C# 的预处理器不能进行宏替换(没有#define MAX 100这种功能)。


一、什么是预处理器指令?

例如:

#define DEBUG using System; class Program { static void Main() { #if DEBUG Console.WriteLine("调试模式"); #endif Console.WriteLine("程序结束"); } }

输出:

调试模式 程序结束

如果没有定义DEBUG

// #define DEBUG

那么:

#if DEBUG Console.WriteLine("调试模式"); #endif

整个代码块不会参与编译。


二、C# 常见预处理器指令

指令作用
#define定义编译符号
#undef取消定义
#if条件编译
#elif否则如果
#else否则
#endif结束条件编译
#warning生成编译警告
#error生成编译错误
#region折叠代码区域
#endregion结束区域
#line修改行号信息
#nullable控制可空引用类型
#pragma控制编译器行为

三、#define

用于定义一个编译符号。

语法:

#define 名称

例如:

#define TEST using System; class Program { static void Main() { #if TEST Console.WriteLine("测试模式"); #endif } }

输出:

测试模式

注意:

  • 必须放在文件最顶部
  • 不能放到 namespace 内
  • 一个文件定义仅影响当前文件

错误示例:

using System; #define TEST

编译错误。


四、#undef

取消定义。

例如:

#define TEST #undef TEST using System; class Program { static void Main() { #if TEST Console.WriteLine("测试"); #else Console.WriteLine("正式"); #endif } }

输出:

正式

五、#if 条件编译

最常见。

例如:

#define DEBUG using System; class Program { static void Main() { #if DEBUG Console.WriteLine("Debug版本"); #endif #if RELEASE Console.WriteLine("Release版本"); #endif } }

输出:

Debug版本

多条件

可以使用:

#if DEBUG && TEST

例如:

#define DEBUG #define TEST #if DEBUG && TEST Console.WriteLine("两个都存在"); #endif

也支持:

#if DEBUG || TEST

以及

#if !DEBUG

六、#elif

例如:

#define WINDOWS #if LINUX Console.WriteLine("Linux"); #elif WINDOWS Console.WriteLine("Windows"); #else Console.WriteLine("Unknown"); #endif

输出:

Windows

七、#else

例如:

#if DEBUG Console.WriteLine("调试"); #else Console.WriteLine("发布"); #endif

八、#endif

结束一个条件块。

例如:

#if DEBUG ... #endif

九、#warning

人为生成一个编译警告。

例如:

#warning 这里还有Bug

Visual Studio:

warning CS1030: 这里还有Bug

程序仍然可以运行。


十、#error

人为生成编译错误。

例如:

#error 当前版本禁止发布

结果:

error CS1029: 当前版本禁止发布

程序无法编译。

适合:

  • 禁止旧版本
  • 禁止错误配置
  • 提醒开发人员

十一、#region

用于代码折叠。

例如:

#region 字段 private int age; private string name; #endregion

IDE 中显示:

▶ 字段

点击即可展开。

也可以:

#region 属性 ... #endregion #region 方法 ... #endregion

大型项目大量使用。


十二、#line

修改编译器认为的行号。

例如:

#line 100 Console.WriteLine("Hello");

如果这里报错:

第100行

而不是实际行号。

也可以:

#line hidden

隐藏行号。

恢复:

#line default

通常用于:

  • 代码生成器
  • Razor
  • T4 模板

十三、#nullable(C# 8.0+)

控制可空引用类型。

开启:

#nullable enable string? name = null;

关闭:

#nullable disable

恢复默认:

#nullable restore

例如:

#nullable enable string name = null;

编译器:

警告: 不能赋值 null

而:

string? name = null;

没有警告。


十四、#pragma

控制编译器行为。

最常见:

#pragma warning disable

例如:

#pragma warning disable CS0168 int a; #pragma warning restore CS0168

表示:

关闭:

变量声明但未使用

之后恢复。

也可以:

#pragma warning disable CS0618

关闭:

过时 API

十五、实际开发中的应用

1. Debug 日志

#if DEBUG Console.WriteLine("开始执行"); #endif

Release 不会编译。


2. 平台区分

#if WINDOWS ... #elif LINUX ... #endif

3. 测试代码

#if TEST RunUnitTest(); #endif

上线自动去除。


4. API 版本控制

#if NET8_0 ... #elif NET6_0 ... #endif

.NET SDK 会自动定义目标框架对应的编译符号。


5. 临时屏蔽警告

#pragma warning disable CS0618 OldMethod(); #pragma warning restore CS0618

十六、注意事项

❌ 错误示例:

#define MAX 100

C# 不支持宏替换。

只能:

#define DEBUG

不能:

#define Version "1.0"

十七、与 C/C++ 的区别

功能C#C/C++
宏替换❌ 不支持✅ 支持
条件编译✅ 支持✅ 支持
包含文件#include❌ 不支持✅ 支持
定义符号✅ 支持✅ 支持
代码折叠✅#region部分编辑器支持
生成警告✅✅

十八、常用预处理器指令速查

指令说明是否常用
#define定义编译符号⭐⭐⭐⭐⭐
#undef取消定义⭐⭐⭐
#if条件编译⭐⭐⭐⭐⭐
#elif条件分支⭐⭐⭐⭐
#else条件分支⭐⭐⭐⭐
#endif结束条件编译⭐⭐⭐⭐⭐
#warning生成编译警告⭐⭐⭐
#error生成编译错误⭐⭐⭐
#region代码折叠⭐⭐⭐⭐⭐
#endregion结束代码区域⭐⭐⭐⭐⭐
#line修改行号信息⭐⭐
#nullable控制可空引用类型⭐⭐⭐⭐
#pragma控制编译器行为⭐⭐⭐⭐

总结

预处理器指令的主要用途是在编译阶段控制代码,而不是在程序运行时改变逻辑。其中,日常开发最常用的是:

  • #if / #elif / #else / #endif:根据编译符号实现条件编译。
  • #region / #endregion:组织和折叠代码,提高可读性。
  • #nullable:启用或控制可空引用类型检查,减少空引用异常。
  • #pragma warning:临时关闭或恢复特定编译警告。

掌握这些指令后,你可以更灵活地管理不同编译配置(如 Debug/Release)、跨平台代码以及大型项目的代码结构。

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

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

立即咨询