實現(xiàn)針對不同.net版本的條件編譯
今天碰到這樣一個需求,寫的C#庫,有時候需要在.net 2.0下編譯,有時候需要在.net 4.0下編譯,這個庫里使用了lambda表達(dá)式,使用了擴展方法,使用了幾個 System.Core.dll 引入的Action類型。
為了在 .net 2.0 下能夠編譯成功,我寫了一個文件 Patch.cs,定義了 System.Runtime.CompilerServices.ExtensionAttribute 類型,這樣就可以在2.0下使用lambda表達(dá)式和擴展方法了,同時,添加了幾個用到的System.Core.dll 引入的Action類型:
- namespace System.Runtime.CompilerServices
- {
- public class ExtensionAttribute : Attribute { }
- }
- namespace System
- {
- public delegate void Action();
- public delegate void Action<T0,T1>(T0 t0,T1 t1);
- }
然而,要在.net 4.0 下編譯,因為類型已經(jīng)存在,必須注釋掉Patch.cs,很麻煩。于是想通過條件編譯來解決,即:
- #if NET2
- namespace System.Runtime.CompilerServices
- {
- public class ExtensionAttribute : Attribute { }
- }
- namespace System
- {
- public delegate void Action();
- public delegate void Action<T0,T1>(T0 t0,T1 t1);
- }
- #endif
問題是,.net 里沒有定義和.net版本有關(guān)的指示符。怎么辦呢?自己動手,豐衣足食,使用Build Events在編譯之前自動偵測出項目所使用的.net版本,定義出我們想要的指示符。
在 C#模板編程(2): 編寫C#預(yù)處理器,讓模板來的再自然一點 一文中,寫了一個程序 Csmacro.exe 來實現(xiàn)C#下的模板機制,本文在Csmacro.exe 的基礎(chǔ)上,增加偵測項目所引用的.net 版本的功能。
原理:查找項目目錄下的 csproj 文件,解析它,找到節(jié)點TargetFrameworkVersion,判斷.net版本,然后生成一個Csmacro_Template.cs文件,在里面 #define 版本指示符。例如,對 .Net 2.0 項目,生成的 Csmacro_Template.cs 文件內(nèi)容為:
- #define NET2
修改后Csmacro的代碼可在:https://github.com/xiaotie/GebCommon 上下載(目前只處理了 .net 2.0 和 4.0,如需要針對其它版本,可自行修改代碼)。有了 Csmacro,一切就好辦了。
第一步,把 Csmacro.exe 放在Path路徑下
第二步,打開需要條件編譯的項目,添加 Pre-build 事件:Csmacro.exe $(ProjectDir)
第三步,編輯源文件,如,Patch.cs 文件修改為:
- #region include "Csmacro_Template.cs"
- #endregion
- #if NET2
- namespace System.Runtime.CompilerServices
- {
- public class ExtensionAttribute : Attribute { }
- }
- namespace System
- {
- public delegate void Action();
- public delegate void Action<T0,T1>(T0 t0,T1 t1);
- }
- #endif
#region include 是我引入的 Csmacro 宏語法。詳見 C#模板編程(2): 編寫C#預(yù)處理器,讓模板來的再自然一點 一文。點擊編譯,系統(tǒng)會生成一個 Patch_Csmacro.cs 文件,內(nèi)容如下:
- #define NET2
- #if NET2
- namespace System.Runtime.CompilerServices
- {
- public class ExtensionAttribute : Attribute { }
- }
- namespace System
- {
- public delegate void Action();
- public delegate void Action<T0,T1>(T0 t0,T1 t1);
- }
- #endif
第四步,把生成的 Patch_Csmacro.cs 添加到項目中來。
搞定以后,選擇不同的target,編譯時產(chǎn)生的就是對該target的條件編譯!
原文鏈接:http://www.cnblogs.com/xiaotie/archive/2012/11/26/2789810.html