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++模板使用那么自然,毕竟又近了一步。:P

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


xiaotie 集异璧实验室(GEBLAB)

相关文章
|
18天前
|
编译器 C++
C++语言预处理器学习应用案例
【4月更文挑战第8天】C++预处理器包括条件编译、宏定义和文件包含等功能。例如,条件编译用于根据平台选择不同代码实现,宏定义可简化常量和变量名,文件包含则用于整合多个源文件。示例中展示了如何使用`#ifdef`等指令进行条件编译,当`DEBUG`宏定义时,`PRINT_LOG`会打印调试信息,否则不执行。
13 1
|
4月前
|
存储 编译器 C语言
【C++11特性篇】模板的新一力将:可变参数模板 [全解析]
【C++11特性篇】模板的新一力将:可变参数模板 [全解析]
|
4月前
|
存储 C++
【C++】可变参数模板使用总结(简洁易懂,详细,含代码演示)
【C++】可变参数模板使用总结(简洁易懂,详细,含代码演示)
|
14天前
|
存储 编译器 Linux
【C++初阶(十)】C++模板(进阶) ---非类型模板参数、模板的特化以及模板的分离编译
【C++初阶(十)】C++模板(进阶) ---非类型模板参数、模板的特化以及模板的分离编译
21 0
|
1月前
|
存储 算法 安全
【C/C++ 模板编程 链接问题】 了解和解决模板编程中的链接错误以及正确的模板编写方式
【C/C++ 模板编程 链接问题】 了解和解决模板编程中的链接错误以及正确的模板编写方式
44 1
|
1月前
|
C++
C/C++ 基础题:预处理器宏中,##的使用场景,什么时候需要使用它?
C/C++ 基础题:预处理器宏中,##的使用场景,什么时候需要使用它?
10 1
|
7月前
|
算法 编译器 C++
如何编写一个通用的函数?
如何编写一个通用的函数?
65 2
|
10月前
|
存储 编译器 程序员
抽丝剥茧C语言(高阶)程序环境和预处理
抽丝剥茧C语言(高阶)程序环境和预处理
|
编译器 Linux C语言
【C++初阶:模板进阶】非类型模板参数 | 模板的特化 | 模板分离编译 上
【C++初阶:模板进阶】非类型模板参数 | 模板的特化 | 模板分离编译
160 0
【C++初阶:模板进阶】非类型模板参数 | 模板的特化 | 模板分离编译 上
|
编译器 C语言 C++
【C++初阶:模板进阶】非类型模板参数 | 模板的特化 | 模板分离编译 下
【C++初阶:模板进阶】非类型模板参数 | 模板的特化 | 模板分离编译
209 0
【C++初阶:模板进阶】非类型模板参数 | 模板的特化 | 模板分离编译 下