“预处理器指令”这些命令从来不会转化为可执行代码的命令,但会影响编译过程的各个方面。例如,使用预处理器指令可以禁止编译代码的某一部分。如果计划发布两个版本的代码,即基本版本和拥有更多功能的企业版本,就可以使用这些预处理器命令。在编译软件的基本版本时,使用预处理器指令可以禁止编译器编译与额外功能相关的代码。另外,在编写提供调试信息的代码时,使用预处理指令可以禁止编译器编译与额外功能相关的代码。另外,在编写提供调试信息的代码时,也可以使用预处理指令。实际上,在销售软件时,一般不希望编译这部分代码。
- #define和undef#defing用法: #define DebugDebug可以看做是声明一个变量,但此变量没有真正的值,只是存在而已。#define单独用没什么意义,一般是和#if结合使用。
- #define用法: #undef Debug作用就是删除Debug的定义。如果Debug符号不存在,这条指令就没有任何作用。如果Debug符号存在,则之前的#define Debug则无效。#define与#undef申明必须放在C#源文件的开头位置,即程序集引用的开头。以下是一个示例:
#define DEBUG1 #define DEBUG2 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; namespace WindowsFormsApplication1 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { #if DEBUG1 MessageBox.Show("Debug version1"); #elif DEBUG2 MessageBox.Show("Debug version2"); #else MessageBox.Show("Debug version3"); #endif #if DEBUG2 MessageBox.Show("Debug version2"); #endif } } }
执行结果:注意:这里需要注意的地方就是对于if语句,从上到下执行,在执行的过程中如果有一个条件满足将终止整个if语句。这与Switch....case语句不同,只要条件满足就可以执行。#elif(=else if)与其含义相同。这里Debug只是一个名称,不是关键字。 - #warning和#error当编译器遇到这两条指令时,会分别产生警告和错误。如果编译器遇到#warning指令,会显示该指令后的文本,之后继续编译。如果遇见#error指令,也会显示指令后面的文本,但会立刻退出编译,不会产生IL代码。(其实和编译器的警告和错误意义相同)以下是一个示例:
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; namespace WindowsFormsApplication1 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { #warning "ALL RIGHT?" { MessageBox.Show("Debug version1"); } #error "ALL RIGHT?" MessageBox.Show("Debug version1"); } } }
注意:当代码编译的过程中遇到error指令时,是无法编译的。 - #region和#endregion将代码进行收缩。
- #line使您可以修改编译器的行号以及(可选)错误和警告的文件名输出。其实功能类似于更改行号。
class MainClass { static void Main() { #line 200 "Special" int i; // CS0168 on line 200 int j; // CS0168 on line 201 #line default char c; // CS0168 on line 9 float f; // CS0168 on line 10 #line hidden // numbering not affected string s; double d; // CS0168 on line 13 } }
- #pragma为编译器提供特殊的指令,以说明如何编译包含带有杂注的文件,这些指令必须是编译器支持的指令。也就是说,不能使用#pragma创建自定义预处理指令。有以下两个指令。(1)#pragma warning 可禁用或启用某些警告。语法如下:#pragma warning disable warning-list#pragma warning restore warning-list以下为示例:
注意:当没有指定警告编号时,disable禁用所有警告,而restore启用所有警告。// pragma_warning.cs using System; #pragma warning disable 414, 3021 [CLSCompliant(false)] public class C { int i = 1; static void Main() { } } #pragma warning restore 3021 [CLSCompliant(false)] // CS3021 public class D { int i = 1; public static void F() { } }
(2)#pargma checksum语法:#pragma checksum "filename" "{guid}" "check bytes"参数“filename”要求监视更改或更新新的文件名称。参数“{guid}”文件的全局唯一标识符(GUID)。参数“checksum_byte”十六进制数的字符串,表示校验和的字节。必须是偶数位的十六进制数。奇数编译会导致编译警告,发生错误。注意:目前不适合ASP.NET项目
class TestClass { static int Main() { #pragma checksum "file.cs" "{3673e4ca-6098-4ec1-890f-8fceb2a794a2}" "{012345678AB}" // New checksum } }