在C#中有许多名为“预处理器指令”的命令。这些命令从来不会转化为可执行代码中的命令,但会影响编译过程的各个方面。例如,使用预处理器指令可以禁止编译器编译代码的某一部分。但需要注意,C#并没有一个像C++那样的独立预处理器,所谓的预处理器指令实际上是由编译器处理的。
以下简要介绍预处理器指令的功能:
1.#define和#undef
#define的用法如下所示:
#define DEBUG 它告诉编译器存在给定名称的符号,在本例中是DEBUG。这个符号并不是实际代码的一部分,而只在编译器编译代码时存在。在C#代码中没有任何意义。
#undef正好相反——它删除符号的定义:
#undef DEBUG 如果符号不存在,#undef没有任何作用。同样,如果符号已经存在,则#define不起作用。
必须把#define和#undef命令放在C#源文件的开头位置,在声明要编译的任何对象的代码之前。
#define的作用体现在与其他预处理器指令(如#if)结合使用时,它的功能就非常强大了。
2.#if,#elif,#else和#endif
这些指令告诉编译器是否要编译某个代码块。下面例子:
void DoSomething(int x) { //do something #if DEBUG Console.WriteLine("x="+x); #endif } 这段代码会像不同代码一样正常编译,但Console.WriteLine命令包含在了#if子句内。这段代码只有在前面的#define命令定义了符号DEBUG后才执行。当编译器遇到#if语句后,将先检查相关的符号是否存在,如果符号存在,就编译#if子句中的代码。否则,忽略代码,直到遇到匹配的#endif指令为止。一般是在调试时定义DEBUG符号的,把相关的调试代码放到#if子句中。在完成调试后注释掉#define语句。这样调试代码就会消失,编译后的文件也会变小。
#elif(=else if)和#else指令可以用在#if块中,也可以嵌套#if块:
#define ENTERPRISE #define W2K
#if ENTERPRISE // do something #if W2K //一些只和ENTERPRISE相关的代码 //在W2K上运行的代码 #endif #elif PROFESSIONAL //do something else #else //something #endif #if和#elif还支持一组逻辑运算符“!”,"==","!=","||"如果符号存在就被认为是true否则为false,例如:
#if W2K && (ENTERPRISE==false) //if W2K is defined but ENTERPRISE is not . 3.#warning和#error
当编译器遇到这两个预处理器指令时会分别产生警告或错误。当编译器遇到#warning指令,会给用户显示#warning指令后面的文本,之后编译继续进行。如果编译器遇到#error指令,就会给用户显示后面的文本,作为一条编译错误消息,然后会立即退出编译,不会产生IL代码。使用这两条指令可以检查#define语句是否做错了什么,#warning可以提醒自己都进行了哪些操作:
#if DEBUG && RELEASE #error "已经定义了DEBUG和RELEASE" #endif #warning "下面是一句没用的输出" Console.WriteLine("hello world"); 4.#region和#endregion
#region和#endregion指令用于把一段代码标记为有给定名称的一个块,如下所示:
#region Member Field Declarations int x; double d; Currency balance; #endregion 这两条指令的优点是他们可以被某些编辑器识别,如Visual Studio .NET编辑器。这些编辑器可以使用这些指令使代码在屏幕上更好地布局。
5.#pragma
#lpragma指令可抑制或还原指定的编译警告。其可以在类或方法级别执行。例:
#pragma warning disable 169 public class MyClass { int neverUsedField; } #pragma warning restore 169 上面的例子禁止“字段未使用”警告,然后在编译MyClass类后还原该警告。
|