C#模板编程(2): 编写C#预处理器,让模板来的再自然一点

在《C#模板编程(1):有了泛型,为什么还需要模板?》文中,指出了C#泛型的局限性,为了突破这个局限性,我们需要模板编程。但是,C#语法以及IDE均不支持C#模板编程,怎么办呢?自己动手,丰衣足食,编写自己的C#预处理器。

一、C#预处理机制设计

问题的关键就是在C#的源文件中引入include机制,设计下面的语法:

(1) 引入:#region include <path> #endregion

(2) 被引:#region mixin … #endgion

例子:假设A.cs需要引用B.cs中的代码。A文件内容为:

复制代码
XXX

#region include "B.cs"
#endregion

XXX
复制代码

B.cs 文件内容为:

复制代码
YYY

#region mixin

MMM

#endregion

ZZZ
复制代码

运行预处理器,对A文件进行处理,生成第三个文件A_.cs:

XXX

MMM

XXX

二、实现

编写预处理器:Csmacro.exe[Csmacro.zip](意思是CSharp Macro)程序,代码如下:

Csmacro

编译之后,放在系统路径下(或放入任一在系统路径下的目录)。然后,在VS的项目属性的Build Events的Pre-build event command line中写入“Csmacro.exe $(ProjectDir)”,即可在编译项目之前,对$(ProjectDir)目录下的所有cs程序进行预处理。

Csmacro.exe 对于包含#region include <path> #endregion代码的程序xx.cs,预处理生成名为 xx_Csmacro.cs的文件;对于文件名以"Csmacro.cs”结尾的文件,则不进行任何处理。

使用时要注意:

(1)#region include <path> 与 #endregion 之间不能有任何代码;

(2)#region mixin 与 #endgion 之间不能有其它的region

(3)不支持多级引用

三、示例

下面,以《C#模板编程(1):有了泛型,为什么还需要模板?》文尾的例子说明怎样编写C#模板程序:

(1)建立一个模板类 FilterHelper_Template.cs ,编译通过:

FilterHelper_Template.cs

 这里,我使用了命名空间Hidden,意思是这个命名空间不想让外部使用,因为它是模板类。

(2)编写实例化模板类 ImageU8FilterHelper.cs

ImageU8FilterHelper.cs

注意:这里使用 partial class 是为了使代码与预处理器生成的代码共存,不产生编译错误。

(3)编译项目,可以发现,预处理器自动生成了代码文件ImageU8FilterHelper_Csmacro.cs,且编译通过:

ImageU8FilterHelper_Csmacro.cs

四、小结

这样一来,C#模板类使用就方便了很多,不必手动去处理模板类的复制和粘帖。虽然仍没有C++模板使用那么自然,毕竟又近了一步。

本文转自xiaotie博客园博客,原文链接http://www.cnblogs.com/xiaotie/archive/2010/03/25/1694278.html如需转载请自行联系原作者


xiaotie 集异璧实验室(GEBLAB)

原文地址:https://www.cnblogs.com/twodog/p/12137934.html