C# 预处理器指令 (详细篇)

简介

除了前面介绍的常用关键字外, c# 还有许多名为 “预处理器指令” 的命令。这些命令从来不会转化为可执行代码中的命令,但会影响编译过程的各个方面。 例如,使用预处理器指令可以禁止编译器编译代码的某一部分。

预处理器指令的开头都是有符号 “#” 

#define 和 # undef

// #define 的用法

#define DEBUG

它告诉编译器存在给定名称的符号, 在本例中是 DEBUG。 这有点类似于声明了一个变量, 但这个变量并没有真正的值,只是存在而已。 这个符号不是实际代码的一部分, 而是在编译器编译代码时存在 

// #undef 正好相反, 它删除符号的定义

#undef DEBUG

如果符号不存在, #undef 就没有任何作用。 同样,如果符号已经存在, 则#define 也不起作用。 

必须把 #define 和 #undef 命令放到 c# 文件的开头位置,在声明要编译的任何对象的代码之前。

#define 本身并没有什么用, 但与其他预处理器指令 (特别是#if) 结合使用时, 它的功能就非常强大了。

注意: 预处理指令不用分号结束, 一般一行只有一条命令。

#if 、 #elif 、 #else 和 # endif

这些指令告诉编译器是否要编译代码块, 考虑下面的代码

int DoSomeWork(double x)
{
    #if DEBUG
        Console.WriteLine("x is " + x);
    #endif
}

这段代码会像往常那样编译, 但 Console.WriteLine 方法调用包含在 #if 子句内。 这行代码只有在前面的 #define 指令定义了符号 DEBUG 后才执行。 当编译器遇到 #if 指令后, 将先检查相关的符号是否存在, 如果符号存在,就编译 #if 子句中的代码。否则,编译器会忽略所有的代码, 知道遇到匹配的 #endif 指令为止。 把与调试相关的代码放到 #if 子句中, 在完成了调试后,就把 #define 指令注释掉, 所有的调试代码会奇迹般地消失, 可执行文件也会变小, 最终用户不会被这些调试信息弄糊涂。

#elif(=else if)和 # else 指令可以用在 #if块中, 其含义非常直观, 也可以嵌套#if 块:

#define ENTERPRISE
#define W10

#if ENTERPRISE
    // do something
 #if W10
     // some code that is only relevant to enterprise
     // edition running on W10
 #endif
#elif PROFESSIONAL
    // do something else
#sele
    // code for the leaner version
#endif

#if 和 # elif 还支持一组逻辑运算符 “!” 、“==” 、“!=”、“||” 。 如果符号存在, 就被认为是 true, 否则为 false, 例如:

#if W10 && (ENTERPRISE==false) 
    // do something
#endif

#warning 和 #error

当编译器遇到它们时, 会分别产生警告或错误。 如果编译器遇到 #warning 指令,会向用户显示 #warning 指令后面的文本,之后编译继续进行。 如果编译器遇到 #error 指令, 就会向用户显示后面的文本, 作为一条编译错误消息, 然后会立即退出编译,不会生成IL代码。

使用这两条指令可以检查 #define语句是不是做错了什么事, 使用#warning语句可以提醒自己执行某个操作:

#if DEBUG && RELEASE
    #error "You've defined DEBUG and RELEASE simultaneously!"
#endif
#warning "Don't forget to remove  this line before the boss tests the code!"
    Console.WriteLine("I hate this job.");

#region 和 #endregion

用于把一段代码视为有给定名称的一个块,如下所示

#region Member Field Declarations

int x;
double d;
Currency balance;

#endregion

这个看起来似乎没有什么用, 它根本不影响编译过程。 这些指令真正的优点是它们可以被某些编译器识别, 这些编译器可以使用这些指令使代码在屏幕上更好的布局

#line

可以用于改变编译器在警告和错误信息中显示的文件名和行号信息。 这条指令用的并不多。 如果编写代码时,在把代码发送给编译器前, 要使用某些软件包改变输入的代码, 该指令最有用, 因为这意味着编译器报告的行号或文件名与文件中的行号或编译的文件名不匹配。 #line 指令可以用于还原这种匹配。 也可以使用 #line default 把行号还原为默认的行号:
 

#line 164 "Core.cs"

#line default

#pragma

可以抑制或还原指定的编译警告。 与命令行选项不同, #pragma 指令可以在类或方法级别实现, 对抑制警告的内容和抑制的时间进行更精细的控制。 下面的例子禁止 “字段未使用” 警告,然后在编译 MyClass 类后还原该警告。

#pragma warning disable 169

public class MyClass
{
    int x;
}

#pragma warning restore 169
发布了27 篇原创文章 · 获赞 0 · 访问量 152

猜你喜欢

转载自blog.csdn.net/weixin_39328209/article/details/105576412