C# 條件編譯 (#if 和 Conditional)

本文主要講述C#中计螺,使用 #if 和 Conditional 特性來按條件編譯代碼的不同原理和適用場景码俩。


本文參考了c# Conditional用法詳解.NET/C# 使用 #if 和 Conditional 特性來按條件編譯代碼的不同原理和適用場景


條件編譯符號和預(yù)處理符號

我們有時會使用 #if DEBUG 或者 [Conditional("DEBUG")] 來讓我們的代碼僅在特定的條件下編譯昙楚。

而這里的 DEBUG 是什么呢刽肠?

在我們編寫的 C# 代碼中纯命,這個叫做 “條件編譯符號”(Conditional compilation symbols)
在項目的構(gòu)建過程中愿题,這個叫做 “定義常量”(Define constants)
而在將 C# 代碼編譯到 dll 的編譯環(huán)節(jié)损俭,這個叫做 “預(yù)處理符號”(Preprocessor symbols)
本文要討論的是 #if 和 Conditional 的使用,這是在 C# 代碼中的使用場景潘酗,因此杆兵,本文后面都將其稱之為 “條件編譯符號”。

對于C#仔夺,與 C 和 C++ 不同琐脏,您不能對符號賦予數(shù)值;C# 中的 #if 語句是 Boolean,僅測試符號是否已定義日裙。

在項目ConsoleApp1設(shè)置中的生成中定義一個條件編譯符號CONDITIONA吹艇。



下面請看ConsoleApp1的示例

using System;

namespace ConsoleApp1
{
    public class Class1
    {
        [Conditional("CONDITIONA")]
        public static void Hello1()
        {
            Console.WriteLine("Hello,我是Conditional條件下才可以執(zhí)行的函數(shù)1");
        }

        public static void Hello2()
        {
#if CONDITIONA
            Console.WriteLine("Hello,我是#if條件下才可以執(zhí)行的函數(shù)語句2");
#endif
        }
    }

    class Hello
    {
        static void Main(string[] args)
        {
            Class1.Hello1();
            Class1.Hello2();
            Console.ReadKey();
        }
    }
}

執(zhí)行結(jié)果

由此,我們得到了#if與Conditional的第一個區(qū)別:
在這段代碼中昂拂,#if CONDITIONA和 #endif 之間的代碼僅在設(shè)置CONDITIONA后會編譯受神,不配置是不會編譯的。
Conditional影響的格侯,是調(diào)用這個方法的代碼鼻听。調(diào)用這個方法的代碼,僅在 CONDITIONA下會編譯联四,在其他配置下是不會編譯的撑碴。

這也引出了#if與Conditional的第二個區(qū)別:
因為 #if CONDITIONA和 #endif 僅僅影響包含在其內(nèi)的代碼塊,因此其僅僅影響寫的這點代碼所在的項目(或者說程序集)碎连。于是使用 #if 只會影響實現(xiàn)代碼灰羽。
而 [Conditional("CONDITIONA")] 影響的是調(diào)用它的代碼,因此可以設(shè)計作為 API 使用——讓目標(biāo)項目(或者程序集)僅在目標(biāo)項目特定的配置下才會編譯鱼辙。

上面是博主呂毅的官方解釋廉嚼,我這里舉個例子吧。
我們新建一個ConsoleApp2,倒戏,添加引用ConsoleApp1.



寫一個新類

using System;
using ConsoleApp1;

namespace ConsoleApp2
{
    class Program
    {
        static void Main(string[] args)
        {
            Class1.Hello1();//Class1是ConsoleApp1中的類
            Class1.Hello2();
            Console.ReadKey();
        }
    }
}

關(guān)鍵就在于設(shè)置這個條件編譯變量上
當(dāng)你為ConsoleApp1項目設(shè)置了CONDITIONA怠噪,Hello2()打印字符串。
當(dāng)你為ConsoleApp2項目設(shè)置了CONDITIONA杜跷,執(zhí)行Hello1()傍念,打印字符串。

實驗:
為ConsoleApp1項目設(shè)置CONDITIONA葛闷,不為ConsoleApp2項目設(shè)置CONDITIONA憋槐。
Hello,我是#if條件下才可以執(zhí)行的函數(shù)語句2

不為ConsoleApp1項目設(shè)置CONDITIONA,為ConsoleApp2項目設(shè)置CONDITIONA淑趾。
Hello,我是Conditional條件下才可以執(zhí)行的函數(shù)1

為ConsoleApp1項目設(shè)置CONDITIONA阳仔,為ConsoleApp2項目設(shè)置CONDITIONA。
Hello,我是Conditional條件下才可以執(zhí)行的函數(shù)1
Hello,我是#if條件下才可以執(zhí)行的函數(shù)語句2

以此為例扣泊,就可以深刻體會以下的結(jié)論了:
因為 #if CONDITIONA和 #endif 僅僅影響包含在其內(nèi)的代碼塊近范,因此其僅僅影響寫的這點代碼所在的項目(或者說程序集)。于是使用 #if 只會影響實現(xiàn)代碼延蟹。
而 [Conditional("CONDITIONA")] 影響的是調(diào)用它的代碼评矩,因此可以設(shè)計作為 API 使用——讓目標(biāo)項目(或者程序集)僅在目標(biāo)項目特定的配置下才會編譯。

用Conditional屬性的方式阱飘,方法是否生效是取決于調(diào)用方斥杜,而用#if方式虱颗,方法是否生效是取決于方法定義所在的程序集。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末蔗喂,一起剝皮案震驚了整個濱河市上枕,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌弱恒,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,548評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件棋恼,死亡現(xiàn)場離奇詭異返弹,居然都是意外死亡,警方通過查閱死者的電腦和手機爪飘,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,497評論 3 399
  • 文/潘曉璐 我一進店門义起,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人师崎,你說我怎么就攤上這事默终。” “怎么了犁罩?”我有些...
    開封第一講書人閱讀 167,990評論 0 360
  • 文/不壞的土叔 我叫張陵齐蔽,是天一觀的道長。 經(jīng)常有香客問我床估,道長含滴,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,618評論 1 296
  • 正文 為了忘掉前任丐巫,我火速辦了婚禮谈况,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘递胧。我一直安慰自己碑韵,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 68,618評論 6 397
  • 文/花漫 我一把揭開白布缎脾。 她就那樣靜靜地躺著祝闻,像睡著了一般。 火紅的嫁衣襯著肌膚如雪赊锚。 梳的紋絲不亂的頭發(fā)上治筒,一...
    開封第一講書人閱讀 52,246評論 1 308
  • 那天,我揣著相機與錄音舷蒲,去河邊找鬼耸袜。 笑死,一個胖子當(dāng)著我的面吹牛牲平,可吹牛的內(nèi)容都是我干的堤框。 我是一名探鬼主播,決...
    沈念sama閱讀 40,819評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼蜈抓!你這毒婦竟也來了启绰?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,725評論 0 276
  • 序言:老撾萬榮一對情侶失蹤沟使,失蹤者是張志新(化名)和其女友劉穎委可,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體腊嗡,經(jīng)...
    沈念sama閱讀 46,268評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡着倾,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,356評論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了燕少。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片卡者。...
    茶點故事閱讀 40,488評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖客们,靈堂內(nèi)的尸體忽然破棺而出崇决,到底是詐尸還是另有隱情,我是刑警寧澤底挫,帶...
    沈念sama閱讀 36,181評論 5 350
  • 正文 年R本政府宣布恒傻,位于F島的核電站,受9級特大地震影響建邓,放射性物質(zhì)發(fā)生泄漏碌冶。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,862評論 3 333
  • 文/蒙蒙 一涝缝、第九天 我趴在偏房一處隱蔽的房頂上張望扑庞。 院中可真熱鬧,春花似錦拒逮、人聲如沸罐氨。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,331評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽栅隐。三九已至,卻和暖如春玩徊,著一層夾襖步出監(jiān)牢的瞬間租悄,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,445評論 1 272
  • 我被黑心中介騙來泰國打工恩袱, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留泣棋,地道東北人。 一個月前我還...
    沈念sama閱讀 48,897評論 3 376
  • 正文 我出身青樓畔塔,卻偏偏與公主長得像潭辈,于是被迫代替她去往敵國和親鸯屿。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,500評論 2 359

推薦閱讀更多精彩內(nèi)容

  • Swift1> Swift和OC的區(qū)別1.1> Swift沒有地址/指針的概念1.2> 泛型1.3> 類型嚴(yán)謹 對...
    cosWriter閱讀 11,111評論 1 32
  • 官網(wǎng) 中文版本 好的網(wǎng)站 Content-type: text/htmlBASH Section: User ...
    不排版閱讀 4,407評論 0 5
  • 專業(yè)考題類型管理運行工作負責(zé)人一般作業(yè)考題內(nèi)容選項A選項B選項C選項D選項E選項F正確答案 變電單選GYSZ本規(guī)程...
    小白兔去釣魚閱讀 9,008評論 0 13
  • Lua 5.1 參考手冊 by Roberto Ierusalimschy, Luiz Henrique de F...
    蘇黎九歌閱讀 13,835評論 0 38
  • 一把敢、溫故而知新 1. 內(nèi)存不夠怎么辦 內(nèi)存簡單分配策略的問題地址空間不隔離內(nèi)存使用效率低程序運行的地址不確定 關(guān)于...
    SeanCST閱讀 7,818評論 0 27