预处理指令

预处理指令是C/C++中比较常用的概念,C#编译器也定义了一部分预处理指令,用于在编译前向编译器传递一些指示,比如根据编译符号选择性地编译某段代码,其用法与C/C++类似。不过要注意,C#的预处理指令并不是C/C++那种文本替换式的宏,它不支持#include,#define也仅仅是定义一个编译符号,并不会做文本替换。这部分内容在实际开发中只有特定几个场景较为常用,这篇笔记我们简单介绍一下。

指令 说明
#define identifier 定义编译符号
#undef identifier 取消定义编译符号
#if expression 如果表达式为true,则编译下面片段
#elif expression 如果表达式为true,则编译下面片段
#else 如果之前#if和#elif表达式均为false,则编译下面片段
#endif 标记结束#if结构
#region name 标记一段代码开始
#endregion name 标记一段代码结束
#warning message 显示编译时警告信息
#error message 显示编译时错误信息
#line indicator 修改编译器信息中显示的行数
#nullable enable 开启可空引用类型的静态检查(C# 8.0)
#pragma warning 提供修改编译器警告信息行为的选项

注:#define和#undef必须出现在文件的开头,即任何代码(包括using和namespace)之前,否则会编译报错。

条件编译

预处理指令最常见的用途是条件编译,即根据是否定义了某个编译符号来决定是否编译某段代码。除了使用#define在源码中定义编译符号,更常见的做法是在工程文件中通过<DefineConstants>配置符号,这样可以为不同环境(如Debug、Release)定义不同的符号。

#define SHOW_DEBUG_INFO

class Program
{
    static void Main()
    {
#if SHOW_DEBUG_INFO
        Console.WriteLine("调试模式");
#else
        Console.WriteLine("发布模式");
#endif
    }
}

#if后面的表达式可以使用!、&&、||、==、!=等运算符以及true、false,与编译符号组合进行判断。

#region 代码折叠

#region和#endregion用于在IDE中将一段代码折叠起来,它只在编辑器中起作用,并不会影响编译结果,常用于将一个大文件按功能分区以便阅读。

#region 字段声明
private int _a;
private int _b;
#endregion

#warning 和 #error

#warning和#error用于在编译时主动产生警告或错误信息,常配合条件编译使用,例如提醒某段代码尚未完成或某个版本不应被发布。

#if !RELEASE
#warning 当前为开发版本,请勿发布
#endif

#nullable

C# 8.0引入了可空引用类型,默认情况下是关闭的,除了可以在工程文件中通过<Nullable>enable</Nullable>全局开启,也可以在源码文件中使用#nullable指令按文件或按片段开启、关闭。有关可空引用类型可参考数据类型章节。

#nullable enable

string? name = null;

此外,#nullable disable可以关闭检查,#nullable restore可以恢复为工程默认设置。

作者:Gacfox
版权声明:本网站为非盈利性质,文章如非特殊说明均为原创,版权遵循知识共享协议CC BY-NC-ND 4.0进行授权,转载必须署名,禁止用于商业目的或演绎修改后转载。