C# 預(yù)處理器指令的用法
1,預(yù)處理器指令的概念
預(yù)處理器指令是指編譯器在實(shí)際編譯開始之前對(duì)信息進(jìn)行預(yù)處理。通常用于簡(jiǎn)化源程序在不同的執(zhí)行環(huán)境中的更改和編譯。例如可以替換文本中的標(biāo)記,將其他內(nèi)容插入源文件,或者通過(guò)移除幾個(gè)部分的文本來(lái)取消一部分文件的編譯。不同于 C 和 C++ 中的指令,在 C# 中不能使用這些指令來(lái)創(chuàng)建宏,而且預(yù)處理器指令必須是一行中唯一的代碼,不能摻雜其它。
示例如下:
#define condition // 定義 condition 字符 using System; public class ExampleProgram { static void Main(string[] args) { #if (condition) // 測(cè)試 condition 是否為真 Console.WriteLine("condition is defined"); #else Console.WriteLine("condition is not defined"); #endif Console.ReadLine(); } }
2,預(yù)處理器指令的定義與使用
在 C# 程序中,所有的預(yù)處理器指令都是以標(biāo)識(shí)符 # 開始,例如 #define 和 #if,并且預(yù)處理器指令之前只能出現(xiàn)空格不能出現(xiàn)任何代碼。另外,預(yù)處理器指令不是語(yǔ)句,因此它們不需要以分號(hào);結(jié)尾。
2.1,可為空上下文
#nullable 預(yù)處理器指令用于設(shè)置可為空注釋上下文和為空警告上下文。#nullable 指令控制著是否可為空注釋是否有效,以及是否給出為 Null 的警告。設(shè)置著每個(gè)上下文要么處于已禁用狀態(tài),要么處于已啟用狀態(tài) 。
下表列出 #nullable 指令的用法:
用法 | 描述 |
---|---|
#nullable disable | 將可為空注釋和警告上下文設(shè)置為“已禁用”。 |
#nullable enable | 將可為空注釋和警告上下文設(shè)置為“已啟用”。 |
#nullable restore | 將可為空注釋和警告上下文還原為項(xiàng)目設(shè)置。 |
#nullable disable annotations | 將可為空注釋上下文設(shè)置為“已禁用”。 |
#nullable enable annotations | 將可為空注釋上下文設(shè)置為“已啟用”。 |
#nullable restore annotations | 將可為空注釋上下文還原為項(xiàng)目設(shè)置。 |
#nullable disable warnings | 將可為空警告上下文設(shè)置為“已禁用”。 |
#nullable enable warnings | 將可為空警告上下文設(shè)置為“已啟用”。 |
#nullable restore warnings | 將可為空警告上下文還原為項(xiàng)目設(shè)置。 |
代碼示例:
using System; public class ExampleProgram { static void Main(string[] args) { string? str; #nullable disable // 將可為空注釋和警告上下文設(shè)置為“已禁用”。 Console.WriteLine(str); // 報(bào)錯(cuò): 使用了未賦值的局部變量“str” #nullable enable // 將可為空注釋和警告上下文設(shè)置為“已啟用”。 Console.WriteLine(str); } }
代碼界面:(PS:筆者使用的代碼編輯器是 Visual Studio 2022)
2.2,定義符號(hào)
可以使用定義符號(hào) #define 和 取消定義符號(hào) #undef 兩個(gè)預(yù)處理器指令來(lái)定義或取消定義條件編譯的符號(hào)。定義符號(hào)可用于 #if 等編譯指令的條件,使用 #define 來(lái)定義符號(hào),將符號(hào)用作傳遞給 #if 指令的表達(dá)式。
代碼示例:
#define VERBOSE // 定義符 #define using System; public class ExampleProgram { static void Main(string[] args) { #if VERBOSE Console.WriteLine("詳細(xì)輸出版本"); #endif } }
代碼執(zhí)行結(jié)果:
詳細(xì)輸出版本
2.3,條件編譯
可以使用以下四個(gè)預(yù)處理器指令來(lái)控制條件編譯:
- #if:打開條件編譯,其中僅在定義了指定的符號(hào)時(shí)才會(huì)編譯代碼。
- #elif:關(guān)閉前面的條件編譯,并基于是否定義了指定的符號(hào)打開一個(gè)新的條件編譯。
- #else:關(guān)閉前面的條件編譯,如果沒(méi)有定義前面指定的符號(hào),打開一個(gè)新的條件編譯。
- #endif:關(guān)閉前面的條件編譯。
代碼示例:
#define condition2 // 定義 condition 字符 using System; public class ExampleProgram { static void Main(string[] args) { #if (condition) Console.WriteLine("condition is defined"); #elif (condition2) // 測(cè)試 condition2 是否為真 Console.WriteLine("condition2 is defined"); #else Console.WriteLine("condition is not defined"); #endif Console.ReadLine(); } }
代碼執(zhí)行結(jié)果:
csharp condition2 is defined
補(bǔ)充:
#if 以及 #else、#elif、#endif、#define 和 #undef 指令,允許在這些指令之間存在一個(gè)或多個(gè)符號(hào)里面包括或排除代碼。其中,#if 指令開頭的條件指令必須以 #endif 指令顯式終止??梢允褂?define 指令你定義一個(gè)符號(hào),通過(guò)將該符號(hào)用作傳遞給 #if 指令的表達(dá)式。條件編譯指令的用法和 C# 中的條件判斷語(yǔ)句 if、elif 和 else 語(yǔ)句差不多。
2.4,定義區(qū)域
可以使用定義區(qū)域符號(hào) #region 和 #endregion 分別表示啟動(dòng)區(qū)域和結(jié)束區(qū)域。這兩個(gè)預(yù)處理器指令來(lái)定義可在大綱中折疊的代碼區(qū)域。利用 #region 和 #endregion 指令,可以指定在使用代碼編輯器的大綱功能時(shí)可展開或折疊的代碼塊。#region 指令后面可跟折疊區(qū)域的名稱。在較長(zhǎng)的代碼文件中,折疊或隱藏一個(gè)或多個(gè)代碼區(qū)域十分方便。
代碼示例:
using System; #region MyClass definition public class ExampleProgram { static void Main(string[] args) { } } #endregion
折疊前:
折疊后:
2.5,錯(cuò)誤和警告信息
可以使用錯(cuò)誤和警告信息指令告訴編譯器生成用戶定義的編譯器錯(cuò)誤和警告,并控制行信息。其中包括 #error、#warning 和 #line 指令。
#error:使用指定的消息生成編譯器錯(cuò)誤。
示例如下:
using System; public class ExampleProgram { static void Main(string[] args) { // 錯(cuò)誤:此方法中的棄用代碼。 #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:更改用編譯器消息輸出的行號(hào)。
示例如下:
using System; public class ExampleProgram { static void Main() { #line 200 "Special" int i; int j; #line default char c; float f; #line hidden // 編號(hào)不受影響 string s; double d; } }
編譯產(chǎn)生以下輸出:
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 指令將下一行的行號(hào)強(qiáng)制設(shè)為 200(盡管默認(rèn)值為 #6);在執(zhí)行下一個(gè) #line 指令前,文件名都會(huì)報(bào)告為“特殊”。
- #line default 指令將行號(hào)恢復(fù)至默認(rèn)行號(hào),這會(huì)對(duì)上一指令重新編號(hào)的行進(jìn)行計(jì)數(shù)。
- #line hidden 指令能對(duì)調(diào)試程序隱藏連續(xù)行,當(dāng)開發(fā)者逐行執(zhí)行代碼時(shí),介于 #line hidden 和下一 #line 指令(假設(shè)它不是其他 #line hidden 指令)間的任何行都將被跳過(guò)。
2.6,雜注
#pragma 為編譯器給出特殊指令以編譯它所在的文件,這些指令必須受編譯器支持。換句話說(shuō),不能使用 #pragma 創(chuàng)建自定義的預(yù)處理指令。
#pragma 指令的語(yǔ)法可定義為: #pragma <pragma-name> <pragma-arguments>,其中 pragma-name 為編譯器支持 pragma 的名稱,pragma-arguments 是特定于 pragma 的參數(shù)。 例如 #pragma warning 表示啟用或禁用警告,#pragma checksum 表示生成校驗(yàn)和。
代碼示例:
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,預(yù)處理器指令的用途
預(yù)處理器指令的用途總結(jié)為以下幾點(diǎn):
- 有利于項(xiàng)目的調(diào)式和運(yùn)行。例如說(shuō)可以使用條件編譯指令控制程序流的執(zhí)行,在實(shí)際的項(xiàng)目中表現(xiàn)為多版本代碼片段控制。
- 在代碼的調(diào)式階段,可以使用錯(cuò)誤和警告信息指令來(lái)禁止編譯不屬于本功能的額外代碼。
- 使用定義區(qū)域指令可以很好折疊和隱藏指定區(qū)域的代碼片段。開發(fā)者可以更好的集中處理關(guān)鍵代碼,在有著多個(gè)代碼區(qū)域的項(xiàng)目十分的方便。
結(jié)語(yǔ)
到此這篇關(guān)于C# 預(yù)處理器指令的用法的文章就介紹到這了,更多相關(guān)C# 預(yù)處理器指令內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
c#使用DotNetZip封裝類操作zip文件(創(chuàng)建/讀取/更新)實(shí)例
DotnetZip是一個(gè)開源類庫(kù),支持.NET的任何語(yǔ)言,可很方便的創(chuàng)建,讀取,和更新zip文件。而且還可以使用在.NETCompact Framework中。2013-11-11C#實(shí)現(xiàn)條形碼識(shí)別的解決方案分享
主流的識(shí)別庫(kù)主要有ZXing.NET和ZBar,OpenCV 4.0后加入了QR碼檢測(cè)和解碼功能,所以本文主要和大家分享了使用ZBar進(jìn)行條形碼識(shí)別的示例代碼,需要的可以參考一下2023-07-07C#中獲取二維數(shù)組的行數(shù)和列數(shù)以及多維數(shù)組各個(gè)維度的長(zhǎng)度
這篇文章介紹了C#中獲取二維數(shù)組的行數(shù)和列數(shù)以及多維數(shù)組各個(gè)維度的長(zhǎng)度,對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-12-12WPF實(shí)現(xiàn)3D翻牌式倒計(jì)時(shí)特效
這篇文章主要為大家詳細(xì)介紹了WPF實(shí)現(xiàn)3D翻牌式倒計(jì)時(shí)特效,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-09-09C#獲取計(jì)算機(jī)名,IP,MAC信息實(shí)現(xiàn)代碼
利用C#獲取計(jì)算機(jī)名,IP,MAC信息如何實(shí)現(xiàn),一直是網(wǎng)友們的頭疼問(wèn)題,本文整理了一些實(shí)現(xiàn)代碼,需要的朋友可以參考下2012-11-11