文章目录
24.1 什么是预处理指令
C# 中没有实际的预处理程序,“预处理”指令由编译器处理,但这个术语被保留了下来。
24.2 基本规则
- 预处理指令必须和 C# 代码在不同的行。
- 预处理指令不需要以分号结尾。
- 包含预处理指令的每一行必须以“#”字符开始。
- “#”字符前可以有空格。
- 在“#”字符和指令之间可以有空格。
- 允许行尾注释。
- 预处理指令所在的行不允许有分隔符注释。
![image-20240113141417324](https://i-blog.csdnimg.cn/blog_migrate/92f4d4a9d154afddd838678ab120f2d3.png#pic_center)
表 24.1 列出了预处理指令。
![image-20240113141604387](https://i-blog.csdnimg.cn/blog_migrate/843367845ffa07d609b9e1e662a3ef2c.png#pic_center)
24.3 符号指令(#define、#undef )
编译符号是只有两种可能状态的标识符,要么被定义,要么未被定义。其具有如下特性:
- 可以是任何标识符(除 true 和 false 外),包括关键字,以及在 C# 代码中声明的标识符。
- 它没有值,不表示字符串。
- #define 声明一个编译符号。
- #undef 取消定义一个编译符号。
![image-20240113142105747](https://i-blog.csdnimg.cn/blog_migrate/bddfbf07e6cb90ad2f59534b9ee4bb36.png#pic_center)
#define 和 #undef 只能用在源文件的第一行,即任何 C# 代码之前。
![image-20240113142140680](https://i-blog.csdnimg.cn/blog_migrate/1f15d07304627de88169c46bd195b06b.png#pic_center)
重复定义已存在的编译符号是被允许的。
![image-20240113142208788](https://i-blog.csdnimg.cn/blog_migrate/a8afbe0a516a70fe9e0cd82a27d61404.png#pic_center)
定义一个标识符相当于将其值设置为 true,取消定义一个标识符相当于设置其值为 false。
24.4 条件编译(#if、#else、#elif、#endif)
条件编译允许根据某个编译符号是否被定义,来标注一段代码是否被编译或跳过。
- #if
- #else
- #elif
- #endif
![image-20240113142403792](https://i-blog.csdnimg.cn/blog_migrate/137fafdddf773199e65a6b4a4e1417a0.png#pic_center)
![image-20240113142521466](https://i-blog.csdnimg.cn/blog_migrate/f935158afda36930ab692f6b4f727273.png#pic_center)
24.5 条件编译结构
#if 和 #endif 需要配对使用,有 #if 指令,则必须有配对的 #endif 指令。
#if 和 #if … #else 结构
![image-20240113142712207](https://i-blog.csdnimg.cn/blog_migrate/97bd48a3a2a98dff719263850c7edfa6.png#pic_center)
#if … #elif 和 #if … #elif … #else
![image-20240113143026314](https://i-blog.csdnimg.cn/blog_migrate/29c7033253b7857aa77d1b8be8976a50.png#pic_center)
24.6 诊断指令(#warning、#error)
诊断指令产生用户自定义的编译时警告及错误消息,其语法如下。需要注意,Message 是字符串,但不需要被引号包围。
![image-20240113143205468](https://i-blog.csdnimg.cn/blog_migrate/9047e2a425c9162293826a07f15284e3.png#pic_center)
当编译器遇到诊断指令时,会输出相关消息。诊断指令的消息会和编译器产生的警告和错误消息列在一起。
![image-20240113143412844](https://i-blog.csdnimg.cn/blog_migrate/9e4573a735d2435cad66acd774a525fc.png#pic_center)
- #error 指令在 #if 结构中,只有满足 #if 条件时才会生成错误消息:“构建失败”。
- #warning 用于提醒程序会回头来清理一段代码。
24.7 行号指令(#line)
行号指令可以做如下事情:
- 改变编译器警告和错误消息报告的出现行数;
- 改变被编译源文件的文件名。
- 对交互式调试器隐藏一些行。
![image-20240113143906518](https://i-blog.csdnimg.cn/blog_migrate/e8553836a9bf5ff4a3756eef4bc2b465.png#pic_center)
例如:
![image-20240113144002272](https://i-blog.csdnimg.cn/blog_migrate/5c714a68674b34ce44a3e53ac3d27bf0.png#pic_center)
24.8 区域指令(#region、#endregion)
区域指令允许标注和有选择性地命名一段代码。区域由一个 #region 指令和其下方某处的一个 #endregion 指令构成。区域功能能够更轻松地浏览和组织代码。
例如,下面的代码定义了区域 Constructors,包含 2 个构造函数 MyClass。如果不想查看其中的代码,可以在 Rider 中将其折叠为一行。
![image-20240113144258104](https://i-blog.csdnimg.cn/blog_migrate/bc93a714f26eeb9c7ba36989ea9f1bb6.png#pic_center)
24.9 警告开关指令(#pragma warning)
使用 #pragma warning 指令可以关闭或重新开启警告消息。
- disable:关闭警告消息。
- restore:开启警告消息。
关闭/开启特定警告消息
例如,下面的代码关闭 2 个警告消息 618 和 414,之后又开启了 618 警告消息。
![image-20240113144642776](https://i-blog.csdnimg.cn/blog_migrate/d20103bc9dd35e5d2ac40cb22bbcda5f.png#pic_center)
关闭/开启所有警告消息
若不带任何数字列表,则命令会应用于所有警告。
![image-20240113144718103](https://i-blog.csdnimg.cn/blog_migrate/62b085c5cb16fde3856ef4092fc7e360.png#pic_center)