编译预处理(pre - processing),是指编译之前的处理,它曾经是C/C++语言中相当重要的语法成分。C#语言中保留了部分预处理功能。但去掉了容易出错或者繁琐的成分,特别是去掉了#include
和定义可替换的宏定义(#define
)等。编译预处理是通过一些预处理指令来完成的。每个预处理指令单独占一行,都以 #好开始。预处理指令可以分成标识声明、条件处理、信息报告、行号标记四类。
1.标识符声明
在预处理过程中,可以对标识符进行定义和取消定义。
#define 定义一个标识符;
#undef "取消定义"一个标识符;
如果一个标识符被定义,它的语义就等同于true
;如果一个标识符没有定义或者被取消定义,那么它的语义就等同于false
。
#define
和#undef
必须在文件中任何“真正代码”前声明,否则在编译时会发生错误。
2.条件处理
用来对程序文本的一部分进行有条件地包括或排除。有四条指令:
#if, #elif, #else, #endif
其中使用的条件是预处理条件表达式。这种表达式是由标识符、常量true
、false
及运算符!
,==
,!=
,&&
,||
和圆括号组成的表达式。其中被定义的标识符的值是true
,否则其值是false
。例如:
#define Debug
class Class1
{
#if Debug
void Trace(string s) {
}
#endif
}
经编译预处理,其实际的代码变成:
class Class1
{
void Trace(string s) {
}
}
条件处理指令可以嵌套。例如:
#define Debug // Debugging on
#undef Trace // Tracing off
class PurchaseTransaction
{
void Commit() {
#if Debug
CheckConsistency();
#if Trace
WriteToLog(this.ToString());
#endif
#endif
CommitHelper();
}
}
3.信息报告
程序中可以将警告和错误信息报告个编译程序。有两条指令:
#error 和 #warning
例如:
#error Code review needed before check - in
#define DEBUG
#if DEBUG && RETALL
#error A build can't be both debug and retail!
#endif
class Class1{
... }
总是产生警告(“Code review needed before check - in
”),并且如果标识符DEBUG
和RETALL
都被定义,还会产生错误。
4.行号标记
行号标记使用#line
指令。其格式是:
#line 行号 "文件名"
#line
的特点使得开发者可以改变编译器输出时使用的行号和源文件名称,例如警告和错误。如果没有#line
指令,那么行号和文件名称自动有编译器定义。
5.代码块
对于一段代码,可以使用#region
和#endregion
来标明指令。其格式是:
#region 代码块的说明
... ... (具体的多行代码)
#endregion
使用代码块的好处在于:集成开发环境中可以将这段代码折叠起来,以节省代码窗口的空间,方便查看别的代码,这在代码很长的情况下尤其有用。