针对不同.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.  namespace System 
  6.  { 
  7.      public delegate void Action(); 
  8.      public delegate void Action<T0,T1>(T0 t0,T1 t1); 

然而,要在.NET 4.0 下编译,因为类型已经存在,必须注释掉Patch.cs,很麻烦。于是想通过条件编译来解决,即:

  1. #if NET2 
  2.  namespace System.Runtime.CompilerServices 
  3.  { 
  4.      public class ExtensionAttribute : Attribute { } 
  5.  } 
  6.  namespace System 
  7.  { 
  8.     public delegate void Action(); 
  9.     public delegate void Action<T0,T1>(T0 t0,T1 t1); 
  10. #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.     public delegate void Action(); 
  13.     public delegate void Action<T0,T1>(T0 t0,T1 t1); 
  14.  
  15. #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.     public delegate void Action(); 
  12.     public delegate void Action<T0,T1>(T0 t0,T1 t1); 
  13.  #endif 

第四步,把生成的 Patch_Csmacro.cs 添加到项目中来。

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

原文链接:http://www.cnblogs.com/xiaotie/archive/2012/11/26/2789810.html

【编辑推荐】

责任编辑:彭凡 来源: 博客园
相关推荐

2012-11-27 10:14:01

.net条件编译

2009-07-02 13:40:45

面试

2010-01-21 18:19:45

VB.NET条件编译

2015-01-22 09:22:47

OpenStack存储云开源云

2009-09-17 13:26:55

.NET方法签名

2010-01-20 11:15:38

CC++编译器

2009-12-17 16:02:58

红旗Linux

2013-03-05 14:51:05

UbuntuKDEGnome

2010-12-20 15:25:36

编译时间.NET

2009-08-04 18:05:37

动态编译ASP.NET

2016-12-01 09:57:24

PHP错误机制

2009-08-14 00:30:09

C#条件编译指令

2012-11-16 10:14:54

Windows 8

2009-12-17 16:53:13

.NET Framew

2009-08-05 17:04:14

.NET委托

2010-04-23 15:34:41

Oracle 数据库

2010-05-18 14:14:03

MySQL关联left

2011-08-01 10:41:59

Xcode 条件编译

2009-12-09 16:43:48

VS.NET 2003

2010-09-16 17:53:12

Java编译
点赞
收藏

51CTO技术栈公众号