实现针对不同.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类型:

 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 下编译,因为类型已经存在,必须注释掉Patch.cs,很麻烦。于是想通过条件编译来解决,即:

 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版本有关的指示符。怎么办呢?自己动手,丰衣足食,使用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 文件修改为:

 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 宏语法。详见 C#模板编程(2): 编写C#预处理器,让模板来的再自然一点 一文。点击编译,系统会生成一个 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 添加到项目中来。

搞定以后,选择不同的target,编译时产生的就是对该target的条件编译!

本文转自xiaotie博客园博客,原文链接http://www.cnblogs.com/xiaotie/archive/2012/11/26/2789810.html如需转载请自行联系原作者


xiaotie 集异璧实验室(GEBLAB)

相关文章
|
4月前
|
存储 文字识别 C#
一个基于百度飞桨封装的.NET版本OCR工具类库 - PaddleOCRSharp
一个基于百度飞桨封装的.NET版本OCR工具类库 - PaddleOCRSharp
101 0
|
5月前
|
数据采集 自然语言处理 搜索推荐
.Net版本二维码生成器,可生成多种格式:WIFI、网址、邮箱等。
.Net版本二维码生成器,可生成多种格式:WIFI、网址、邮箱等。
44 0
|
6月前
|
开发框架 JavaScript .NET
.NET 8 候选版本 2 (RC2) 现已可用
.NET 8 候选版本 2 (RC2) 现已可用
67 0
.NET 8 候选版本 2 (RC2) 现已可用
|
9月前
|
开发框架 JavaScript 前端开发
.NET 8新预览版本使用 Blazor 组件进行服务器端呈现
.NET 8新预览版本使用 Blazor 组件进行服务器端呈现
160 0
.NET 8新预览版本使用 Blazor 组件进行服务器端呈现
|
11月前
|
API 开发工具 C#
一个.Net版本的ChatGPT SDK
根据OpenAI的开放API,封装的.Net SDK
145 0
|
NoSQL Redis 数据安全/隐私保护
.net core工具组件系列之Redis—— 第一篇:Windows环境配置Redis(5.x以上版本)以及部署为Windows服务
Cygwin工具编译Redis Redis6.x版本是未编译版本(官方很调皮,所以没办法,咱只好帮他们编译一下了),所以咱们先下载一个Cygwin,用它来对Redis进行编译。
192 0
.net core工具组件系列之Redis—— 第一篇:Windows环境配置Redis(5.x以上版本)以及部署为Windows服务
|
监控 Windows
一个基于Quartz.Net开发的Windows版本的进程监控
一个基于.Net 4开发的进程监控系统。此项目可用于监控系统的运行情况,支持按天周月指定时间自动重启,进程添加、编辑监控等。
88 0
一个基于Quartz.Net开发的Windows版本的进程监控
|
开发框架 Prometheus 监控
《快来为你的.NET应用加个监控吧!》更新版本啦
《快来为你的.NET应用加个监控吧!》更新版本啦
228 0
《快来为你的.NET应用加个监控吧!》更新版本啦
|
传感器 编解码 算法
Google Earth Engine ——MOD17A3H.006: Terra Net Primary Production Yearly Global 500m这是该产品的NASA版本年度净初级
Google Earth Engine ——MOD17A3H.006: Terra Net Primary Production Yearly Global 500m这是该产品的NASA版本年度净初级
295 0
Google Earth Engine ——MOD17A3H.006: Terra Net Primary Production Yearly Global 500m这是该产品的NASA版本年度净初级
.NET Micro Framework V4.2 QFE2新版本简介
.NET Micro Framework V4.2 QFE2最新版改变
743 0