实现针对不同.net版本的条件编译
今天碰到这样一个需求,写的C#库,有时候需要在.net 2.0下编译,有时候需要在.net 4.0下编译,这个库里使用了lambda表达式,使用了扩展方法,使用了几个 System.Core.dll 引入的Action类型。
为了在 .net 2.0 下能够编译成功,我写了一个文件 Patch.cs,定义了 System.Runtime.CompilerServices.ExtensionAttribute 类型,这样就可以在2.0下使用lambda表达式和扩展方法了,同时,添加了几个用到的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 下编译,因为类型已经存在,必须注释掉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版本有关的指示符。怎么办呢?自己动手,丰衣足食,使用Build Events在编译之前自动侦测出项目所使用的.net版本,定义出我们想要的指示符。
在 C#模板编程(2): 编写C#预处理器,让模板来的再自然一点 一文中,写了一个程序 Csmacro.exe 来实现C#下的模板机制,本文在Csmacro.exe 的基础上,增加侦测项目所引用的.net 版本的功能。
原理:查找项目目录下的 csproj 文件,解析它,找到节点TargetFrameworkVersion,判断.net版本,然后生成一个Csmacro_Template.cs文件,在里面 #define 版本指示符。例如,对 .Net 2.0 项目,生成的 Csmacro_Template.cs 文件内容为:
- #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#预处理器,让模板来的再自然一点 一文。点击编译,系统会生成一个 Patch_Csmacro.cs 文件,内容如下:
- #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,编译时产生的就是对该target的条件编译!
原文链接:http://www.cnblogs.com/xiaotie/archive/2012/11/26/2789810.html
相关文章
- Windows10安装ElasticSearch笔记
- Windows 11 用户反馈无法安装 1 月更新,导致出现 0x800f0831 等错误
- 八个鲜为人知但很实用的Web API
- TypeScript 编译性能优化:Project Reference
- 什么是 Firefox ESR?如何在 Ubuntu 中安装它?
- 游戏实测显示 Windows 11 比 Ubuntu 更能发挥英伟达 RTX 3080/3090 显卡性能
- 已持续三周多时间,Windows 11 的 12 月更新让 AMD 用户头疼
- 宏碁发布 Aspire S 一体机和 Aspire 5/3 笔记本:搭载 Intel 第 12/13 代酷睿处理器
- 用于高效 Web 开发的十个 Visual Studio 代码扩展
- Nest 的实现原理?理解了 Reflect Metadata 就懂了
- Windows 11 和 Ubuntu 谁更能激发 AMD Radeon 7900XTX 显卡的性能?实测告诉你
- Windows 11 学院:如何禁用 Windows Update 通知
- Windows 11学院:如何启用本地安全机构(LSA)保护功能
- Windows 11 学院:如何启用本地安全机构(LSA)保护功能
- Windows 11 学院:如何启用 / 禁用固定应用到任务栏功能
- Golang网络编程Net包浅析
- Windows 11 学院:如何在稳定版 Windows 11 中使用截图工具的录屏功能
- 修复导致 Windows 10 / Windows 11 设备蓝屏问题,英特尔发布 Wi-Fi 驱动 22.190.0 更新
- Windows 11 预览版个性化新功能:允许用户在桌面上绘制贴纸
- Windows 11 学院:如何强制让 Windows 11 设备蓝屏