.net 2.0 和 4.0不同的.net版本的條(tiáo)件編譯
今天碰到(dào)這樣一個需求,寫的(de)C#庫,有時候需要(yào)在(zài).net 2.0下編譯,有(yǒu)時候需要在.net 4.0下編譯,這個(gè)庫裏使(shǐ)用了lambda表達式,使(shǐ)用了(le)擴展方法(fǎ),使用了幾個 System.Core.dll 引入(rù)的Action類型(xíng)。為了在(zài) .net 2.0 下能(néng)夠編(biān)譯成功(gōng),我(wǒ)寫了一個文件 Patch.cs,定義(yì)了 System.Runtime.CompilerServices.ExtensionAttribute 類型,這樣就可以在2.0下(xià)使用lambda表達式(shì)和擴(kuò)展方法了(le),同時,添加(jiā)了幾(jǐ)個用到的(de)System.Core.dll 引入的Action類(lèi)型:
1: namespace System.Runtime.CompilerServices
2: {
3: public class ExtensionAttribute : Attribute { }
4: } 5: 6: namespace System
7: {
8: public delegate void Action();
9: public delegate void Action<T0,T1>(T0 t0,T1 t1);
10: }
11:
然而,要在.net 4.0 下編譯,因為類型(xíng)已(yǐ)經存在(zài),必須注(zhù)釋掉(diào)Patch.cs,很麻(má)煩。於(yú)是想通過條(tiáo)件(jiàn)編(biān)譯來解決,即:
1: #if NET2
2:
3: namespace System.Runtime.CompilerServices
4: {
5: public class ExtensionAttribute : Attribute { }
6: }
7:
8: namespace System
9: {
10: public delegate void Action();
11: public delegate void Action<T0,T1>(T0 t0,T1 t1);
12: }
13:
14: #endif
問題是,.net 裏沒有定義和.net版本有(yǒu)關的(de)指示(shì)符。怎麽辦(bàn)呢(ne)?自己(jǐ)動手,豐衣足(zú)食,使用Build Events在編譯之前自動偵測出項目所使用的(de).net版本,定義出我們想要的指示符。
在 C#模板(bǎn)編程(chéng)(2): 編寫C#預處理器,讓模板來的再自然(rán)一點 一文中,寫了一個程序 Csmacro.exe 來實現C#下(xià)的(de)模板(bǎn)機製,本文在Csmacro.exe 的基礎上,增加偵測項目所引用的(de).net 版本的功能(néng)。
原理(lǐ):查找(zhǎo)項目(mù)目錄下的 csproj 文件(jiàn),解析它,找到節(jiē)點TargetFrameworkVersion,判斷.net版本,然後生成(chéng)一個Csmacro_Template.cs文件,在裏麵 #define 版本(běn)指示符。例如,對 .Net 2.0 項目,生成的 Csmacro_Template.cs 文件內容為:
#define NET2
修改後Csmacro的(de)代碼可在(zài):https://github.com/xiaotie/GebCommon 上下載(目前(qián)隻(zhī)處理(lǐ)了 .net 2.0 和 4.0,如需(xū)要針(zhēn)對其它版本(běn),可自行修改代碼(mǎ))。有了 Csmacro,一切就好辦了。
第一步,把(bǎ) Csmacro.exe 放在(zài)Path路徑下
第二步,打開需要條件編譯的(de)項(xiàng)目,添加(jiā) Pre-build 事件:Csmacro.exe $(ProjectDir)
第三步,編輯源文件,如,Patch.cs 文件修改為:
1: #region include "Csmacro_Template.cs"
2: #endregion
3:
4: #if NET2
5:
6: namespace System.Runtime.CompilerServices
7: {
8: public class ExtensionAttribute : Attribute { }
9: }
10:
11: namespace System
12: {
13: public delegate void Action();
14: public delegate void Action<T0,T1>(T0 t0,T1 t1);
15: }
16:
17: #endif
#region include 是我引入的 Csmacro 宏(hóng)語(yǔ)法。詳見 C#模板編程(2): 編寫C#預處理器,讓模板來的再自然(rán)一點 一文。點擊編譯,係統會生成(chéng)一個(gè) Patch_Csmacro.cs 文件,內容如下:
1: #define NET2
2:
3: #if NET2
4:
5: namespace System.Runtime.CompilerServices
6: {
7: public class ExtensionAttribute : Attribute { }
8: }
9:
10: namespace System
11: {
12: public delegate void Action();
13: public delegate void Action<T0,T1>(T0 t0,T1 t1);
14: }
15:
16: #endif
第四步,把生成的 Patch_Csmacro.cs 添加到項(xiàng)目中來(lái)。
搞定以後,選擇不(bú)同的(de)target,編譯時產(chǎn)生的就是對該target的(de)條件編譯!
關鍵(jiàn)詞(cí):.net
閱讀(dú)本文後您有什麽感想? 已有(yǒu) 人給出評價(jià)!
- 0
- 0
- 0
- 0
- 0
- 0