|
參考地址:http://blog.csdn.net/alwaysrun/archive/2009/08/20/4467270.aspx http://www./Programming/csharp/200910/11700.htm
C和C++有一類語句稱作預(yù)處理器指令。C#也具有這樣一套預(yù)處理器指令。三種語言使用相同的方法:要求在特定的指令前放置一個#符號。與 C 和 C++ 指令不同,不能使用這些指令創(chuàng)建宏。所有的預(yù)處理器指令必須出現(xiàn)在它們自己的指令行。 在C/C++中,實際上有兩個編譯回合,通過預(yù)處理器指令可以改寫源代碼,使它在第二遍編譯前與特定的結(jié)構(gòu)和應(yīng)用相對應(yīng)。C#的編譯過程不是兩個階段,不過,C#對待預(yù)處理器指令的方式與C/C++相似。 C# 語言的預(yù)處理器指令: - #if
- #else
- #elif
- #endif
- # define
- #undef
- #warning
- #error
- #line
- #region
- #endregion
- #pragma
- #pragma warning
- #pragma checksum
一、#if #if 使您可以開始條件指令,測試一個或多個符號以查看它們是否計算為 true。如果它們的計算結(jié)果確實為 true,則編譯器將計算位于 #if 與最近的 #endif 指令之間的所有代碼。以 #if 指令開始的條件指令必須用 #endif 指令顯式終止。例如: #define DEBUG // ... #if DEBUG Console.WriteLine("Debug version"); #endif 可以使用運算符 ==(相等)、!=(不相等)、&&(與)及 ||(或)來計算多個符號。還可以用括號將符號和運算符分組。 備注: 使用 #if 以及 #else、#elif、#endif、#define 和 #undef 指令,可以包括或排除基于由一個或多個符號組成的條件的代碼。這在編譯調(diào)試版本的代碼或編譯特定配置時最為有用。
二、#else #else 允許您創(chuàng)建復(fù)合條件指令,因此,如果前面的 #if 或(可選)#elif 指令中的任何表達式都不為 true,則編譯器將計算 #else 與后面的 #endif 之間的所有代碼。 備注:#endif必須是#else的下一個預(yù)處理器指令。
三、#elif 使您得以創(chuàng)建復(fù)合條件指令。如果前面的 #if 和前面的任何 #elif(可選)指令表達式的計算結(jié)果都不是 true,則將計算 #elif 表達式。如果 #elif 表達式計算為 true,編譯器將計算位于 #elif 和下一個條件指令之間的所有代碼。 三、#endif #endif 指定以 #if 指令開頭的條件指令的結(jié)尾。 四、#define 使用 #define 可以定義一個符號,并通過將該符號用作表達式傳遞給 #if 指令,使該表達式的計算結(jié)果為 true??梢远x符號,但是無法對符號賦值。例如: # define DEBUG 符號可用于指定編譯的條件。可以使用 #if 或 #elif 來測試符號。還可以使用 conditional 屬性執(zhí)行條件編譯。 也可以用 /define 編譯器選項來定義符號??梢杂?#undef 來取消定義符號。 用 #define 創(chuàng)建的符號的范圍是在其中定義該符號的文件。 備注:與C/C++不一樣,C#的#define語句僅允許你在符號表中插一個標簽,但你不能給任何一個符號賦一個值。與C/C++另一個不同的地方,C/C++允許#define預(yù)處理器指令出現(xiàn)在任何所需的地方,而在使用任何非預(yù)處理器指令的指令前,C#的#define指令必須出現(xiàn)在一個文件中。用#define定義的標簽不會與同名的變量沖突。這就是說,一個變量名不應(yīng)該傳遞給預(yù)處理器指令,而且符號只能通過預(yù)處理器指令來求值。插入到符號表中的標簽的作用域就是定義它的文件??梢杂?undef取消符號定義。
五、#undef #undef 使您可以取消符號的定義,以便通過將該符號用作 #if 指令中的表達式,使表達式的計算結(jié)果為 false。 六、#warning #warning 使您得以從代碼的特定位置生成一級警告。例如: #warning Deprecated code in this method. 備注: #warning 通常用在條件指令中。也可以用 #error(C# 參考)生成用戶定義的錯誤。 示例 // preprocessor_warning.cs // CS1030 expected #define DEBUG class MainClass { static void Main() { #if DEBUG #warning DEBUG is defined #endif } } 七、#error #error 使您可以從代碼中的特定位置生成錯誤。例如: #error Deprecated code in this method. 八、#line #line 使您可以修改編譯器的行號以及(可選)錯誤和警告的文件名輸出。下面的示例說明如何報告與行號關(guān)聯(lián)的兩個警告。#line 200 指令強迫行號為 200(盡管默認值為 #7)。另一行 (#9) 作為默認 #line 指令的結(jié)果跟在通常序列后。 class MainClass { static void Main() { #line 200 int i; // CS0168 on line 200 #line default char c; // CS0168 on line 9 } } 備注: #line 指令可能由生成過程中的自動中間步驟使用。例如,如果行從原始的源代碼文件中移除,但是您仍希望編譯器基于文件中的原始行號生成輸出,則可以移除行,然后用 #line 模擬原始行號。 #line hidden 指令對調(diào)試器隱藏若干連續(xù)的行,這樣當開發(fā)人員在逐句通過代碼時,將會跳過 #line hidden 和下一個 #line 指令(假定它不是另一個 #line hidden 指令)之間的所有行。此選項也可用來使 ASP.NET 能夠區(qū)分用戶定義的代碼和計算機生成的代碼。盡管 ASP.NET 是此功能的主要使用者,但很可能將有更多的源生成器使用它。 #line hidden 指令不會影響錯誤報告中的文件名或行號。即,如果在隱藏塊中遇到錯誤,編譯器將報告當前文件名和錯誤的行號。 #line filename 指令指定您希望出現(xiàn)在編譯器輸出中的文件名。默認情況下,使用源代碼文件的實際名稱。文件名必須括在雙引號 ("") 中。 源代碼文件可以具有 #line 指令的任何編號。 示例 下面的示例說明調(diào)試器如何忽略代碼中的隱藏行。運行此示例時,它將顯示三行文本。但是,當設(shè)置如示例所示的斷點并按 F10 鍵逐句通過代碼時,您將看到調(diào)試器忽略了隱藏行。還請注意,即使在隱藏行上設(shè)置斷點,調(diào)試器仍會忽略它。 // preprocessor_linehidden.cs using System; class MainClass { static void Main() { Console.WriteLine("Normal line #1."); //這里設(shè)置斷點 #line hidden Console.WriteLine("Hidden line."); #line default Console.WriteLine("Normal line #2."); } } 九、#region #region 使您可以在使用 Visual Studio 代碼編輯器的大綱顯示功能時指定可展開或折疊的代碼塊。例如: #region MyClass definition public class MyClass { static void Main() { } } #endregion 備注: #region 塊必須以 #endregion 指令終止。 #region 塊不能與 #if 塊重疊。但是,可以將 #region 塊嵌套在 #if 塊內(nèi),或?qū)?#if 塊嵌套在 #region 塊內(nèi)。 十、#endregion #endregion 標記 #region 塊的結(jié)尾。 十一、#pragma #pragma 用于給編輯器提供特殊的指令,說明如何編譯包含雜注的文件。 #pragma pragma-name pragma-arguments 參數(shù) pragma-name 可識別雜注的名稱。 pragma-arguments 雜注特定的參數(shù)。 十二、#pragma warning #pragma warning 可用于啟用或禁用某些警告。 #pragma warning disable warning-list #pragma warning restore warning-list 參數(shù) warning-list 警告編號的逗號分隔列表。只輸入數(shù)字,不包括前綴 "CS"。 當沒有指定警告編號時,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() { } } 十三、#pragma checksum 可用于生成源文件的校驗和,以幫助調(diào)試 ASP.NET 頁。 #pragma checksum "filename" "{guid}" "checksum bytes" 參數(shù) "filename" 要求監(jiān)視更改或更新的文件的名稱。 "{guid}" 文件的全局唯一標識符 (GUID)。 "checksum_bytes" 十六進制數(shù)的字符串,表示校驗和的字節(jié)。必須是偶數(shù)位的十六進制數(shù)。奇數(shù)位的數(shù)字會導(dǎo)致編譯時警告,從而使指令被忽略。 備注: Visual Studio 調(diào)試器使用校驗和來確保找到的總是正確的源。編譯器計算源文件的校驗和,然后將輸出發(fā)出到程序數(shù)據(jù)庫 (PDB) 文件。最后,調(diào)試器使用 PDB 來比較它為源文件計算的校驗和。 此解決方案不適用于 ASP.NET 項目,因為算出的是生成的源文件而不是 .aspx 文件的校驗和。為解決此問題,#pragma checksum 為 ASP.NET 頁提供了校驗和支持。 在 Visual C# 中創(chuàng)建 ASP.NET 項目時,生成的源文件包含 .aspx 文件(從該文件生成源文件)的校驗和。然后,編譯器將此信息寫入 PDB 文件。 如果編譯器在該文件中沒有遇到 #pragma checksum 指令,它將計算校驗和,然后將算出的值寫入 PDB 文件。 示例 class TestClass { static int Main() { #pragma checksum "file.cs" "{3673e4ca-6098-4ec1-890f-8fceb2a794a2}" "{012345678AB}" // New checksum } }
|