掌握 C# 预处理器指令:条件编译、诊断控制与代码组织实战
C# 预处理器指令完全指南
深度解析 C# 预处理器指令:条件编译、符号定义、警告/错误控制、行号重写、代码分区与编译器指示,附实战示例与最佳实践。
预处理器指令是编译器在正式编译前处理的命令。它们控制哪些代码参与编译、如何处理警告错误、甚至修改编译器对行号/文件名的诊断视图。
C# 中指令以 # 开头,单行结束(无需分号)。
| 指令 | 作用 | 语法示例 |
|---|---|---|
#if | 表达式为真时包含代码 | #if DEBUG
// 调试代码
#endif |
#elif | #if 后的备选条件 | #if COND1
...
#elif COND2
...
#endif |
#else | 前序条件均假时执行 | #if COND
...
#else
...
#endif |
#endif | 结束条件编译块 | #if COND ... #endif |
#define | 定义编译符号 | #define TESTING |
#undef | 取消符号定义 | #undef TESTING |
#warning | 发出一级编译警告 | #warning 此处待重构 |
#error | 发出编译错误,阻止构建 | #error 不支持的平台 |
#line | 重写编译器行号/文件名 | #line 100 "Generated.cs" |
#region | 定义可折叠代码区域(IDE 支持) | #region 初始化
...
#endregion |
#pragma | 向编译器传递特殊指令 | #pragma warning disable CS0168 |
定义与取消符号
#define:创建符号,在#if中求值为true。必须出现在文件首行(前面只能有注释)。#undef:移除符号,使其求值为false。
示例
#define TESTING // 定义符号
#undef TESTING // 取消符号
条件编译:#if、#elif、#else、#endif
#if测试表达式;表达式为真时编译内部代码。- 表达式支持逻辑运算符:
&&(与)、||(或)、!(非)及符号组合。 #elif串联多个条件;#else兜底;#endif必须闭合。
实战示例
#define CSHARP
#undef PYTHON
using System;
namespace Directive {
class ConditionalDirective {
static void Main(string[] args) {
#if (CSHARP && PYTHON)
Console.WriteLine("CSHARP 和 PYTHON 均已定义");
#elif (CSHARP && !PYTHON)
Console.WriteLine("CSHARP 已定义,PYTHON 未定义");
#elif (!CSHARP && PYTHON)
Console.WriteLine("PYTHON 已定义,CSHARP 未定义");
#else
Console.WriteLine("CSHARP 和 PYTHON 均未定义");
#endif
}
}
}
输出:CSHARP 已定义,PYTHON 未定义
生成警告与错误
#warning:输出用户自定义警告,不阻止编译。#error:输出致命错误,立即终止编译。
警告示例
using System;
namespace Directives {
class WarningDirective {
public static void Main(string[] args) {
#if (!CSHARP)
#warning CSHARP 未定义
#endif
Console.WriteLine("#warning 指令示例");
}
}
}
编译输出包含警告行,但程序仍可运行,控制台打印文本。
错误示例
using System;
namespace Directive {
class Error {
public static void Main(string[] args) {
#if (!CSHARP)
#error CSHARP 未定义
#endif
Console.WriteLine("#error 指令示例");
}
}
}
编译失败,报错 CSHARP 未定义,最后一行永不执行。
自定义诊断位置:#line
- 修改后续代码的报告行号与文件名,常用于代码生成工具。
示例
using System;
namespace Directive {
class LineDemo {
public static void Main(string[] args) {
#line 200 "AnotherProgram.cs"
#warning Actual warning generated by Program.cs on line 10
}
}
}
结果:警告显示为 AnotherProgram.cs(200,22): warning CS1030: ...
代码区域组织:#region / #endregion
- 将相关代码分组,Visual Studio 等 IDE 可折叠/展开。
- 区域不能重叠,但可嵌套在条件编译块内。
示例
using System;
namespace Directive {
class RegionDemo {
public static void Main(string[] args) {
#region Hello
Console.WriteLine("Hello");
Console.WriteLine("Hello");
Console.WriteLine("Hello");
Console.WriteLine("Hello");
Console.WriteLine("Hello");
#endregion
}
}
}
输出:五行 "Hello"。
高级编译器控制:#pragma
- 细粒度控制编译器行为。
- 常用场景:
#pragma warning disable:禁用所有警告#pragma warning restore:恢复警告#pragma warning disable CS0168:仅禁用特定警告(如“变量已声明但未使用”)#pragma checksum:生成校验和用于调试
示例
using System;
namespace Directive {
class PragmaDemo {
public static void Main(string[] args) {
#pragma warning disable
#warning 这是警告 1
#pragma warning restore
#warning 这是警告 2
}
}
}
仅显示第二个警告。
深入参考:#pragma (C# 参考)
C语言
- 3D 打印 vs CNC 加工:为您的项目选择正确工具
- CNC加工中SFM代表什么?
- C#关键字与标识符:规则、完整列表与最佳实践
- 掌握 C++ 变量、字面量与常量:核心概念与实战指南
- 深入理解 C++ 数据类型:基础类型、修饰符与最佳实践
- C 语言关键字与标识符完全指南
- C 语言数据类型详解:int、float、char 等核心类型完全指南
- 深入理解 C 预处理器 (CPP):它如何简化编译过程
- C++预处理器指令详解:#define宏、条件编译、#/#运算符与预定义宏
- Python关键字与标识符:掌握保留字与命名规范
- Python 正则表达式 (re 模块) 实战指南
- 精通 Python time 模块:函数、结构体与实战示例