文档章节

实现针对不同.net版本的条件编译

迷你卡卡西
 迷你卡卡西
发布于 2015/04/29 11:59
字数 733
阅读 8
收藏 0

今天碰到这样一个需求,写的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的条件编译!

本文转载自:http://www.cnblogs.com/xiaotie/archive/2012/11/26/2789810.html

共有 人打赏支持
迷你卡卡西
粉丝 6
博文 18
码字总数 503
作品 0
大连
高级程序员
Traits技术初探

概述: traits是一种特性萃取技术,它在Generic Programming中被广泛运用,常常被用于使不同的类型可以用于相同的操作,或者针对不同类型提供不同的实现.traits在实现过程中往往需要用到以下三种...

Sean-x
2016/03/21
24
0
从Trace和Debug来看条件编译(Conditional Compilation)

条件编译,顾名思义,就是根据在编译时指定的条件决定最后需要编译的代码。条件编译是我们可以针对某些特性的环境编写相应的代码,比如有写的代码只需要在Debug模式下才需要执行,有些代码仅...

长平狐
2012/09/04
86
0
.NET Standard 2.0 新版标准:整齐划一的目标

最近结束的.NET Connect 2016大会上,几位微软MVP针对.NET标准的内容和未来发展谈论了自己的看法。 在两个月前公布.NETStandard 2.0时,微软认为新版标准的目标在于为现有的三个主要.NET平台...

达尔文
2016/12/03
7.9K
22
C/C++ 预定义宏

一、GNUC / GNUG 1 GNUC / GNUG是gcc / g++编译器编译代码时预定义的一个宏。需要针对gcc / g++编写代码时, 可以使用该宏进行条件编译。 2 GNUC / GNUG的值表示gcc / g++的版本。需要针对g...

吃一堑消化不良
2016/10/05
44
0
MySQL · 捉虫动态 · 5.6 与 5.5 InnoDB 不兼容导致 crash

bug 背景 RDS的备份工具用的是 Percona-XtraBackup(后面简称PXB),这个工具包里有2个重要的工具,innobackupex和xtrabackup,后者是C编译出的二进制文件,负责备份 InnoDB 数据,前者是一个...

阿里云RDS-数据库内核组
2015/05/04
0
0

没有更多内容

加载失败,请刷新页面

加载更多

vue组件传值之(父子)

⚠️组件的作用域是孤立的,vue解决组件传值问题是通过props ⚠️子传父的时候需要vm.$emit触发实例上的事件,页面需要定一个方法去取值 ⚠️一定要注意命名方式和书写,例如mylChart和myl-c...

peakedness丶
8分钟前
0
0
SpringBoot开发案例之整合Dubbo分布式服务

前言 在 SpringBoot 很火热的时候,阿里巴巴的分布式框架 Dubbo 不知是处于什么考虑,在停更N年之后终于进行维护了。在之前的微服务中,使用的是当当维护的版本 Dubbox,整合方式也是使用的 ...

微笑向暖wx
22分钟前
0
0
TypeScript基础入门之装饰器(二)

转发 TypeScript基础入门之装饰器(二) 装饰器求值 如何应用装饰器应用于类内的各种声明的顺序: 1. 对每个实例成员应用参数装饰器,后跟Method,Accessor或Property Decorators。 2. 对每个静...

durban
22分钟前
0
0
Java程序员年薪40W是什么水平?税前还是税后?

很多人学Java都是冲着Java的高薪来的,那么搞Java的程序员,年薪40W到底是个什么水平呢,本文达妹和大家一起探讨一下。 前几天在论坛看到这么一个问题,搞Java的程序员年薪40w是什么水平?一...

架构师springboot
27分钟前
1
0
区块链100讲:盘点那些常用的加密算法原理

在开发过程中,常常用到各种加密方法和算法,本文总结了几种常用加密方法的原理。 1 对称加密 原理:加密和解密数据使用同一个密钥,适合对大量数据进行加解密 安全性:关键是密钥的保存方式...

HiBlock
41分钟前
0
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部