像C語言一樣,C#有一些預處理器指令的命令。例如,#if#end if,#define等,所謂這些命令是指不會轉化為可執行代碼中的一些命令,只是在編譯的過程中起作用。
下面簡要介紹一下:
1 、#define和 #undef
#define的用法如下所示:
#define DEBUG
它告訴編譯器存在給定名稱的符號,在本例中是DEBUG。這有點類似於聲明一個變量,但這個變量並沒有真正的值,只是存在而已。這個符號不是實際代碼的一部分,而只在編譯器編譯代碼時存在。在C#代碼中它沒有任何意義。
#undef正好相反-- 刪除符號的定義:
#undef DEBUG
如果符號不存在,#undef就沒有任何作用。同樣,如果符號已經存在,#define也不起作用。必須把#define和#undef命令放在C#源代碼的開頭,在聲明要編譯的任何對象的代碼之前。#define本身並沒有什麼用,但與其他預處理器指令(特別是#if)結合使用時,它的功能就非常強大了。
注意:
這裡應注意一般C#語法的一些變化。預處理器指令不用分號結束,一般一行上只有一個命令。這是因為對於預處理器指令,C#不再要求命令用分號結束。如果它遇到一個預處理器指令,就會假定下一個命令在下一行上。
2、#if, #elif, #else和#endif
這些指令告訴編譯器是否要編譯某個代碼塊。考慮下面的方法:
[csharp] int DoSomeWork(double x)
{
// do something
#if DEBUG
Console.WriteLine("x is " + x);
#endif
}
int DoSomeWork(double x)
{
// do something
#if DEBUG
Console.WriteLine("x is " + x);
#endif
}
這段代碼會像往常那樣編譯,但Console.WriteLine命令包含在#if子句內。這行代碼只有在前面的#define命令定義了符號DEBUG後才執行。當編譯器遇到#if語句後,將先檢查相關的符號是否存在,如果符號存在,就編譯#if塊中的代碼。否則,編譯器會忽略所有的代碼,直到遇到匹配的#endif指令為止。一般是在調試時定義符號DEBUG,把與調試相關的代碼放在#if子句中。
在完成了調試後,就把#define語句注釋掉,所有的調試代碼會奇跡般地消失,可執行文件也會變小,最終用戶不會被這些調試信息弄糊塗(顯然,要做更多的測試,確保代碼在沒有定義DEBUG的情況下也能工作)。
#elif (=else if)和#else指令可以用在#if塊中,其含義非常直觀。也可以嵌套#if塊:
[csharp]
#define ENTERPRISE
#define W2K
// further on in the file
#if ENTERPRISE
// do something
#if W2K
// some code that is only relevant to enterprise
// edition running on W2K
#endif
#elif PROFESSIONAL
// do something else
#else
// code for the leaner version
#endif
#define ENTERPRISE
#define W2K
// further on in the file
#if ENTERPRISE
// do something
#if W2K
// some code that is only relevant to enterprise
// edition running on W2K
#endif
#elif PROFESSIONAL
// do something else
#else
// code for the leaner version
#endif
#if和 #elif還支持一組邏輯運算符!、==、!=和 ||。如果符號存在,就被認為是true,否則為false。
3、#warning和 # error
另外兩個非常有用的預處理器指令是#warning和#error,當編譯器遇到它們時,會分別產生警告或錯誤。如果編譯器遇到#warning指令,會給用戶顯示#warning指令後面的文本,之後編譯繼續進行。如果編譯器遇到#error指令,就會給用戶顯示後面的文本,作為一個編譯錯誤信息,然後會立即退出編譯,不會生成IL代碼。使用這兩個指令可以檢查#define語句是不是做錯了什麼事,使用#warning語句可以讓自己想起做過什麼事:
[csharp]
#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*");
#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*");
4、 #region和#endregion
#region和 #endregion指令用於把一段代碼標記為有給定名稱的一個塊,如下所示。
[csharp]
#region
Member Field Declarationsint x;
double d;
Currency balance;
#endregion
#region
Member Field Declarationsint x;
double d;
Currency balance;
#endregion
這看起來似乎沒有什麼用,它不影響編譯過程。這些指令的優點是它們可以被某些編輯器識別,包括Visual Studio編輯器。這些編輯器可以使用這些指令使代碼在屏幕上更好地布局。
5 、 #line
#line指令可以用於改變編譯器在警告和錯誤信息中顯示的文件名和行號信息。這個指令用得並不多。如果編寫代碼時,在把代碼發送給編譯器前,要使用某些軟件包改變鍵入的代碼,就可以使用這個指令,因為這意味著編譯器報告的行號或文件名與文件中的行號或編輯的文件名不匹配。#line指令可以用於恢復這種匹配。也可以使用語法#line default把行號恢復為默認的行號:
[csharp]
#line 164 "Core.cs" // we happen to know this is line 164 in the file
// Core.cs, before the intermediate
// package mangles it.
// later on
#line 164 "Core.cs" // we happen to know this is line 164 in the file
// Core.cs, before the intermediate
// package mangles it.
// later on
6、 #pragma
#pragma指令可以抑制或恢復指定的編譯警告。與命令行選項不同,#pragma指令可以在類或方法上執行,對抑制警告的內容和抑制的時間進行更精細的控制。下面的例子禁止字段使用警告,然後在編譯MyClass類後恢復該警告。
[csharp]
#pragma warning disable 169
public class MyClass
{
int neverUsedField;
}
#pragma warning restore 169
摘自 yysyangyangyangshan