C# 語言的前置處理器指令–轉載+體會

來源:互聯網
上載者:User

     參考地址:http://blog.csdn.net/alwaysrun/archive/2009/08/20/4467270.aspx

                  http://www.bianceng.cn/Programming/csharp/200910/11700.htm

    C和C++有一類語句稱作前置處理器指令。C#也具有這樣一套前置處理器指令。三種語言使用相同的方法:要求在特定的指令前放置一個#符號。與 C 和 C++ 指令不同,不能使用這些指令建立宏。所有的前置處理器指令必須出現在它們自己的指令行。

    在C/C++中,實際上有兩個編譯回合,通過前置處理器指令可以改寫原始碼,使它在第二遍編譯前與特定的結構和應用相對應。C#的編譯過程不是兩個階段,不過,C#對待前置處理器指令的方式與C/C++相似。

 

C# 語言的前置處理器指令:

  • #if
  • #else
  • #elif
  • #endif
  • # define
  • #undef
  • #warning
  • #error
  • #line
  • #region
  • #endregion
  • #pragma
  • #pragma warning
  • #pragma checksum

一、#if
         #if 使您可以開始條件指令,測試一個或多個符號以查看它們是否計算為 true。如果它們的計算結果確實為 true,則編譯器將計算位於 #if 與最近的 #endif 指令之間的所有代碼。以 #if 指令開始的條件指令必須用 #endif 指令顯式終止。例如:

#define DEBUG
// ...
#if DEBUG
    Console.WriteLine("Debug version");
#endif

         可以使用運算子 ==(相等)、!=(不相等)、&&(與)及 ||(或)來計算多個符號。還可以用括弧將符號和運算子分組。

備忘:
         使用 #if 以及 #else、#elif、#endif、#define 和 #undef 指令,可以包括或排除基於由一個或多個符號組成的條件的代碼。這在編譯調試版本的代碼或編譯特定配置時最為有用。

二、#else
         #else 允許您建立複合條件指令,因此,如果前面的 #if 或(可選)#elif 指令中的任何錶達式都不為 true,則編譯器將計算 #else 與後面的 #endif 之間的所有代碼。

備忘:#endif必須是#else的下一個前置處理器指令。

三、#elif

         使您得以建立複合條件指令。如果前面的 #if 和前面的任何 #elif(可選)指令運算式的計算結果都不是 true,則將計算 #elif 運算式。如果 #elif 運算式計算為 true,編譯器將計算位於 #elif 和下一個條件指令之間的所有代碼。

三、#endif
         #endif 指定以 #if 指令開頭的條件指令的結尾。

四、#define
         使用 #define 可以定義一個符號,並通過將該符號用作運算式傳遞給 #if 指令,使該運算式的計算結果為 true。可以定義符號,但是無法對符號賦值。例如:

         # define DEBUG

         符號可用於指定編譯的條件。可以使用 #if 或 #elif 來測試符號。還可以使用 conditional 屬性執行條件編譯。
         也可以用 /define 編譯器選項來定義符號。可以用 #undef 來取消定義符號。 用 #define 建立的符號的範圍是在其中定義該符號的檔案。

備忘:與C/C++不一樣,C#的#define語句僅允許你在符號表中插一個標籤,但你不能給任何一個符號賦一個值。與C/C++另一個不同的地方,C/C++允許#define前置處理器指令出現在任何所需的地方,而在使用任何非前置處理器指令的指令前,C#的#define指令必須出現在一個檔案中。用#define定義的標籤不會與同名的變數衝突。這就是說,一個變數名不應該傳遞給前置處理器指令,而且符號只能通過前置處理器指令來求值。插入到符號表中的標籤的範圍就是定義它的檔案。可以用#undef取消符號定義。

五、#undef
         #undef 使您可以取消符號的定義,以便通過將該符號用作 #if 指令中的運算式,使運算式的計算結果為 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 使您可以修改編譯器的行號以及(可選)錯誤和警告的檔案名稱輸出。下面的樣本說明如何報告與行號關聯的兩個警告。#line 200 指令強迫行號為 200(儘管預設值為 #7)。另一行 (#9) 作為預設 #line 指令的結果跟在通常序列後。

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 指令對調試器隱藏若干連續的行,這樣當開發人員在逐句通過代碼時,將會跳過 #line hidden 和下一個 #line 指令(假定它不是另一個 #line hidden 指令)之間的所有行。此選項也可用來使 ASP.NET 能夠區分使用者定義的代碼和電腦產生的程式碼。儘管 ASP.NET 是此功能的主要使用者,但很可能將有更多的源產生器使用它。
         #line hidden 指令不會影響錯誤報表中的檔案名稱或行號。即,如果在隱藏塊中遇到錯誤,編譯器將報告當前檔案名稱和錯誤的行號。
         #line filename 指令指定您希望出現在編譯器輸出中的檔案名稱。預設情況下,使用原始碼檔案的實際名稱。檔案名稱必須括在雙引號 ("") 中。 原始碼檔案可以具有 #line 指令的任何編號。

樣本
         下面的樣本說明調試器如何忽略代碼中的隱藏行。運行此樣本時,它將顯示三行文本。但是,當設定如樣本所示的斷點並按 F10 鍵逐句通過代碼時,您將看到調試器忽略了隱藏行。還請注意,即使在隱藏行上設定斷點,調試器仍會忽略它。
// preprocessor_linehidden.cs
using System;
class MainClass
{
    static void Main()
    {
        Console.WriteLine("Normal line #1."); //這裡設定斷點
#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 塊內,或將 #if 塊嵌套在 #region 塊內。

十、#endregion
#endregion 標記 #region 塊的結尾。

十一、#pragma
#pragma 用於給編輯器提供特殊的指令,說明如何編譯包含雜注的檔案。
#pragma pragma-name pragma-arguments
參數
pragma-name
可識別雜注的名稱。
pragma-arguments
雜注特定的參數。

十二、#pragma warning
#pragma warning 可用於啟用或禁用某些警告。
#pragma warning disable warning-list
#pragma warning restore warning-list
參數
warning-list
警告編號的逗號分隔列表。只輸入數字,不包括首碼 "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
可用於產生源檔案的校正和,以協助調試 ASP.NET 頁。
#pragma checksum "filename" "{guid}" "checksum bytes"
參數
"filename"
要求監視更改或更新的檔案的名稱。
"{guid}"
檔案的通用唯一識別碼 (GUID)。
"checksum_bytes"
十六進位數的字串,表示校正和的位元組。必須是偶數位的十六進位數。奇數位的數字會導致編譯時間警告,從而使指令被忽略。
備忘:
Visual Studio 調試器使用校正和來確保找到的總是正確的源。編譯器計算源檔案的校正和,然後將輸出發出到程式資料庫 (PDB) 檔案。最後,調試器使用 PDB 來比較它為源檔案計算的校正和。
此解決方案不適用於 ASP.NET 項目,因為算出的是產生的源檔案而不是 .aspx 檔案的校正和。為解決此問題,#pragma checksum 為 ASP.NET 頁提供了校正和支援。
在 Visual C# 中建立 ASP.NET 項目時,產生的源檔案包含 .aspx 檔案(從該檔案產生源檔案)的校正和。然後,編譯器將此資訊寫入 PDB 檔案。
如果編譯器在該檔案中沒有遇到 #pragma checksum 指令,它將計算校正和,然後將算出的值寫入 PDB 檔案。
樣本
class TestClass
{
    static int Main()
    {
        #pragma checksum "file.cs" "{3673e4ca-6098-4ec1-890f-8fceb2a794a2}" "{012345678AB}" // New checksum
    }
}

 

 

 

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.