介紹
預處理指令是由編譯器解釋的命令,並影響輸出或生成過程中的行為. 使用術語“預處理指令”只是為了與 C 和 C++ 編程語言保持一致。在 C# 中沒有單獨的預處理步驟,不像C和C++中,你不可以使用這些指令創建宏。預處理指令總是占用源代碼中的單獨一行,並且總是以 # 字符和預處理指令名稱開頭。# 字符的前面以及 # 字符與指令名稱之間可以出現空白符。
接下來我們看看有關以下 C# 預處理器指令的信息:
#IF
如果 C# 編譯器遇到最后面跟有 #endif 指令的 #if 指令,則僅當指定的符號已定義時,它才會編譯這兩個指令之間的代碼。
C# 中的 #if 語句是 Boolean,僅測試符號是否已定義。
運算符 &&(與)和 ||(或)可用來評估多個符號是否已定義。 還可以用括號將符號和運算符分組。
結合使用 #if 與 #else、#elif、#endif、#define 和 #undef 指令,可以根據一個或多個符號是否存在來包含或排除代碼。在編譯調試版本的代碼或針對特定配置進行編譯時,這會很有用。
以 #if 指令開始的條件指令必須用 #endif 指令顯式終止。
#Else
#else 允許您創建復合條件指令,因此,如果前面的 #if 或(可選)#elif 指令中的任何表達式都不為 true,則編譯器將計算 #else 與后面的 #endif 之間的所有代碼。
#Elif
#elif 使您得以創建復合條件指令。如果前面的 #if 和前面的任何 #elif(可選)指令表達式的計算結果都不是 true,則將計算 #elif 表達式。如果 #elif 表達式計算為 true,編譯器將計算位於 #elif 和下一個條件指令之間的所有代碼。
使用 #elif 更簡單,因為每個 #if 都需要一個 #endif,而 #elif 即使在沒有匹配的 #endif 時也可以使用。
#Endif
#endif 指定以 #if 指令開頭的條件指令的結尾
#Define
#define 可讓您定義符號。 當您將符號用作傳遞給 #if 指令的表達式時,此表達式的計算結果為 true
注意:不能像在 C 和 C++ 中的通常做法一樣,使用 #define 指令來聲明常數值。最好是將 C# 中的常數定義為類或結構的靜態成員。如果具有多個像這樣的常數,可以考慮創建一個單獨的“Constants”類來保存這些常數。
針對以上指令我們提供一段代碼:
如上所示:由於DEBUG 和 MYTEST都定義了,所以,如下代碼
#elif (DEBUG && MYTEST) Console.WriteLine("DEBUG and MYTEST are defined");
高亮顯示可用,其他行代碼置灰。
運行結果:
#Undef
#undef 使您可以取消符號的定義,以便通過將該符號用作 #if 指令中的表達式,使表達式的計算結果為 false。
示例代碼:
#define DEBUG #undef DEBUG using System; class MyClass { static void Main() { #if DEBUG Console.WriteLine("DEBUG is defined"); #else Console.WriteLine("DEBUG is not defined"); #endif } }
運行結果:
#Warning
#warning 使您得以從代碼的特定位置生成一級警告。 例如:
#define DEBUG class MainClass { static void Main() { #if DEBUG #warning DEBUG is defined #endif } }
#Error
#error使您可以從代碼中的特定位置生成錯誤。例如:
#define DEBUG class MainClass { static void Main() { #if DEBUG #error DEBUG is defined #endif } }
#Region
#region 是大家最為熟悉的指令,它使您可以在使用 Visual Studio 代碼編輯器的大綱顯示功能時指定可展開或折疊的代碼塊。 在較長的代碼文件中,能夠折疊或隱藏一個或多個區域會十分便利,這樣,您可將精力集中於當前處理的文件部分。 下面的示例演示如何定義區域:
#region MyClass definition public class MyClass { static void Main() { } } #endregion
#region 塊必須以 #endregion 指令終止。
#region 塊不能與 #if 塊重疊。但是,可以將 #region 塊嵌套在 #if 塊內,或將 #if 塊嵌套在 #region 塊內。
#endregion
#endregion 標記 #region 塊的結尾
#line
#line 使您可以修改編譯器的行號以及(可選)錯誤和警告的文件名輸出。 下面的示例說明如何報告與行號關聯的兩個警告。 #line 200 指令將行號強制設置為 200(盡管默認行號為 #7),在執行下一條 #line 指令之前,文件名將報告為“Special”。 #line default 指令將行號恢復為默認行號,默認行號對前一條指令重新編號的行進行計數。
輸出結果:
備注
#line 指令可能由生成過程中的自動中間步驟使用。例如,如果行從原始的源代碼文件中移除,但是您仍希望編譯器基於文件中的原始行號生成輸出,則可以移除行,然后用 #line 模擬原始行號。
#line hidden 指令對調試器隱藏若干連續的行,這樣當開發人員在逐句通過代碼時,將會跳過 #line hidden 和下一個 #line 指令(假定它不是另一個 #line hidden 指令)之間的所有行。此選項也可用來使 ASP.NET 能夠區分用戶定義的代碼和計算機生成的代碼。盡管 ASP.NET 是此功能的主要使用者,但很可能將有更多的源生成器使用它。
#line hidden 指令不會影響錯誤報告中的文件名或行號。即,如果在隱藏塊中遇到錯誤,編譯器將報告當前文件名和錯誤的行號。
#line filename 指令指定您希望出現在編譯器輸出中的文件名。默認情況下,使用源代碼文件的實際名稱。文件名必須用雙引號 ("") 引起來且前面必須帶一個行號。
源代碼文件可以具有 #line 指令的任何編號。
示例 1
下面的示例說明調試器如何忽略代碼中的隱藏行。運行此示例時,它將顯示三行文本。但是,當設置如示例所示的斷點並按 F10 鍵逐句通過代碼時,您將看到調試器忽略了隱藏行。還請注意,即使在隱藏行上設置斷點,調試器仍會忽略它。
#pragma
#pragma 為編譯器提供特殊的指令,以說明如何編譯包含雜注的文件。 這些指令必須是編譯器支持的指令。 也就是說,不能使用 #pragma 創建自定義預處理指令。Microsoft C# 編譯器支持以下兩個 #pragma 指令:
#pragma warning
#pragma checksum
在日常開發的過程中我們總是會經常對代碼進行編譯,而在編譯的過程中會出現許多信息,許多無用的警告信息總是會在編譯過程中提示出來,以干擾一些主要的警告,對此也是可以通過預處理器指令來進行關閉來阻止其顯示。
#pragma warning 可啟用或禁用某些警告。
在創建的項目中,打開“輸出”窗口(這樣可以查看輸出的警告編號:如(CS0414)):Debug->Windows->Output,如下圖所示:
然后我們做個測試:
using System; class MainClass { static void Main() { int i = 5; Console.ReadLine(); } } public class test { int i = 10; }
對於如上代碼,經過編譯后出現如下類似警告:“變量i被分配,但從來沒有使用過它的值”。
如果我們不想顯示這些警告,可通過:#pragma warning disable 警告編號1, 警告編號2,來消除。
如上圖所示,警告編號分別為CS0219,CS0414
注意:消除的編號不帶”CS”,如下代碼:
#pragma warning disable 0219,0414 using System; class MainClass { static void Main() { int i = 5; Console.ReadLine(); } } public class test { int i = 10; }
編譯項目查看輸出結果:
沒有警告了。
如果我們又想顯示CS0414怎么辦呢?
可以使用#pragma warning restore 警告編號1
如下代碼:
#pragma warning disable 0219,0414 using System; class MainClass { static void Main() { int i = 5; Console.ReadLine(); } } #pragma warning restore 0414 public class test { int i = 10; }
編譯項目,查看輸出結果:
CS0414警告又顯示出來了。
#pragma checksum
關於#pragma checksum指令我沒能理解,google了一下也沒找到相關示例。
這里給出MSDN鏈接:http://msdn.microsoft.com/zh-cn/library/vstudio/ms173226.aspx
大家可以自行參考,希望熟悉的朋友可以給出解釋和示例,幫助大家。