首頁 > 軟體

C# 前處理器指令的用法

2023-11-22 14:00:24

1,前處理器指令的概念

前處理器指令是指編譯器在實際編譯開始之前對資訊進行預處理。通常用於簡化源程式在不同的執行環境中的更改和編譯。例如可以替換文字中的標記,將其他內容插入原始檔,或者通過移除幾個部分的文字來取消一部分檔案的編譯。不同於 C 和 C++ 中的指令,在 C# 中不能使用這些指令來建立宏,而且前處理器指令必須是一行中唯一的程式碼,不能摻雜其它。

範例如下:

#define condition       // 定義 condition 字元
using System;

public class ExampleProgram
{
    static void Main(string[] args)
    {
        #if (condition)         // 測試 condition 是否為真
            Console.WriteLine("condition is defined");
        #else
            Console.WriteLine("condition is not defined");
        #endif
            Console.ReadLine(); 
    }
}

2,前處理器指令的定義與使用

在 C# 程式中,所有的前處理器指令都是以識別符號 # 開始,例如 #define 和 #if,並且前處理器指令之前只能出現空格不能出現任何程式碼。另外,前處理器指令不是語句,因此它們不需要以分號;結尾。

2.1,可為空上下文

#nullable 前處理器指令用於設定可為空註釋上下文和為空警告上下文。#nullable 指令控制著是否可為空註釋是否有效,以及是否給出為 Null 的警告。設定著每個上下文要麼處於已禁用狀態,要麼處於已啟用狀態 。

下表列出 #nullable 指令的用法:

用法描述
#nullable disable將可為空註釋和警告上下文設定為“已禁用”。
#nullable enable將可為空註釋和警告上下文設定為“已啟用”。
#nullable restore將可為空註釋和警告上下文還原為專案設定。
#nullable disable annotations將可為空註釋上下文設定為“已禁用”。
#nullable enable annotations將可為空註釋上下文設定為“已啟用”。
#nullable restore annotations將可為空註釋上下文還原為專案設定。
#nullable disable warnings將可為空警告上下文設定為“已禁用”。
#nullable enable warnings將可為空警告上下文設定為“已啟用”。
#nullable restore warnings將可為空警告上下文還原為專案設定。

程式碼範例:

using System;

public class ExampleProgram
{
    static void Main(string[] args)
    {
        string? str;

    #nullable disable       // 將可為空註釋和警告上下文設定為「已禁用」。 
        Console.WriteLine(str);         // 報錯: 使用了未賦值的區域性變數「str」

    #nullable enable        // 將可為空註釋和警告上下文設定為「已啟用」。 
        Console.WriteLine(str);
    }
}

程式碼介面:(PS:筆者使用的程式碼編輯器是 Visual Studio 2022)

2.2,定義符號

可以使用定義符號 #define 和 取消定義符號 #undef 兩個前處理器指令來定義或取消定義條件編譯的符號。定義符號可用於 #if 等編譯指令的條件,使用 #define 來定義符號,將符號用作傳遞給 #if 指令的表示式。

程式碼範例:

#define VERBOSE     // 定義符 #define
using System;

public class ExampleProgram
{
    static void Main(string[] args)
    {
        #if VERBOSE
                Console.WriteLine("詳細輸出版本");
        #endif
    }
}

程式碼執行結果:

詳細輸出版本

2.3,條件編譯

可以使用以下四個前處理器指令來控制條件編譯:

  • #if:開啟條件編譯,其中僅在定義了指定的符號時才會編譯程式碼。
  • #elif:關閉前面的條件編譯,並基於是否定義了指定的符號開啟一個新的條件編譯。
  • #else:關閉前面的條件編譯,如果沒有定義前面指定的符號,開啟一個新的條件編譯。
  • #endif:關閉前面的條件編譯。

程式碼範例:

#define condition2       // 定義 condition 字元
using System;

public class ExampleProgram
{
    static void Main(string[] args)
    {
        #if (condition)
            Console.WriteLine("condition is defined");
        #elif (condition2)      // 測試 condition2 是否為真 
            Console.WriteLine("condition2 is defined");
        #else
            Console.WriteLine("condition is not defined");
        #endif
            Console.ReadLine();
    }
}

程式碼執行結果:

csharp condition2 is defined

補充:

#if 以及 #else、#elif、#endif、#define 和 #undef 指令,允許在這些指令之間存在一個或多個符號裡面包括或排除程式碼。其中,#if 指令開頭的條件指令必須以 #endif 指令顯式終止。可以使用#define 指令你定義一個符號,通過將該符號用作傳遞給 #if 指令的表示式。條件編譯指令的用法和 C# 中的條件判斷語句 if、elif 和 else 語句差不多。

2.4,定義區域

可以使用定義區域符號 #region 和 #endregion 分別表示啟動區域和結束區域。這兩個前處理器指令來定義可在大綱中摺疊的程式碼區域。利用 #region 和 #endregion 指令,可以指定在使用程式碼編輯器的大綱功能時可展開或摺疊的程式碼塊。#region 指令後面可跟摺疊區域的名稱。在較長的程式碼檔案中,摺疊或隱藏一個或多個程式碼區域十分方便。

程式碼範例:

using System;

#region MyClass definition
public class ExampleProgram
{
    static void Main(string[] args)
    {
    }
}
#endregion

摺疊前:

摺疊後:

2.5,錯誤和警告資訊

可以使用錯誤和警告資訊指令告訴編譯器生成使用者定義的編譯器錯誤和警告,並控制行資訊。其中包括 #error、#warning 和 #line 指令。

#error:使用指定的訊息生成編譯器錯誤。

範例如下:

using System;

public class ExampleProgram
{
    static void Main(string[] args)
    {
        // 錯誤:此方法中的棄用程式碼。
        #error Deprecated code in this method.      
        Console.WriteLine("This is Deprecated code");
    }
}

程式碼介面:

#warning:使用指定的訊息生成編譯器警告。

範例如下:

using System;

public class ExampleProgram
{
    static void Main(string[] args)
    {
        // 警告:此方法中的棄用程式碼。
        #warning Deprecated code in this method.
        Console.WriteLine("This is Deprecated code");
    }
}

程式碼介面:

#line:更改用編譯器訊息輸出的行號。

範例如下:

using System;

public class ExampleProgram
{
    static void Main()
    {
#line 200 "Special"
        int i;
        int j;
#line default       
        char c;
        float f;
#line hidden        // 編號不受影響
        string s;
        double d;
    }
}

編譯產生以下輸出:

Special(200,13): warning CS0168: The variable ‘i’ is declared but never used
Special(201,13): warning CS0168: The variable ‘j’ is declared but never used
MainClass.cs(9,14): warning CS0168: The variable ‘c’ is declared but never used
MainClass.cs(10,15): warning CS0168: The variable ‘f’ is declared but never used
MainClass.cs(12,16): warning CS0168: The variable ‘s’ is declared but never used
MainClass.cs(13,16): warning CS0168: The variable ‘d’ is declared but never used

  • #line 200 指令將下一行的行號強制設為 200(儘管預設值為 #6);在執行下一個 #line 指令前,檔名都會報告為“特殊”。
  • #line default 指令將行號恢復至預設行號,這會對上一指令重新編號的行進行計數。
  • #line hidden 指令能對偵錯程式隱藏連續行,當開發者逐行執行程式碼時,介於 #line hidden 和下一 #line 指令(假設它不是其他 #line hidden 指令)間的任何行都將被跳過。

2.6,雜注

#pragma 為編譯器給出特殊指令以編譯它所在的檔案,這些指令必須受編譯器支援。換句話說,不能使用 #pragma 建立自定義的預處理指令。

#pragma 指令的語法可定義為: #pragma <pragma-name> <pragma-arguments>,其中 pragma-name 為編譯器支援 pragma 的名稱,pragma-arguments 是特定於 pragma 的引數。 例如 #pragma warning 表示啟用或禁用警告,#pragma checksum 表示生成校驗和。

程式碼範例:

using System;

#pragma warning disable 414, CS3021
[CLSCompliant(false)]
public class C
{
    int i = 1;
    static void Main()
    {
    }
}

#pragma warning restore CS3021
[CLSCompliant(false)]         
public class D
{
    int i = 1;
    public static void F()
    {
    }
}

程式碼介面:

3,前處理器指令的用途

前處理器指令的用途總結為以下幾點:

  • 有利於專案的調式和執行。例如說可以使用條件編譯指令控制程式流的執行,在實際的專案中表現為多版本程式碼片段控制。
  • 在程式碼的調式階段,可以使用錯誤和警告資訊指令來禁止編譯不屬於本功能的額外程式碼。
  • 使用定義區域指令可以很好摺疊和隱藏指定區域的程式碼片段。開發者可以更好的集中處理關鍵程式碼,在有著多個程式碼區域的專案十分的方便。

結語

到此這篇關於C# 前處理器指令的用法的文章就介紹到這了,更多相關C# 前處理器指令內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com