在《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)

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

  1. C++模板编程:如何使非通用的模板函数实现声明和定义分离

    我们在编写C++类库时,为了隐藏实现,往往只能忍痛舍弃模版的强大特性.但如果我们只需要有限的几个类型的模版实现,并且不允许用户传入其他类型时,我们就可以将实例化的代码放在cpp文件中实现了.然而,当我 ...

  2. C语言--- 字符串数组 、 预处理器和预处理指令 、 多文件编程 、 结构体

    1 输入一个姓名,判断是否是五虎上将. 1.1 问题 本案例需要使用交互的方式判断:用户从控制台输入一个名字,由程序判断该名字是否在五虎上将的名单中.五虎上将的名单是:GuanYu.ZhangFei. ...

  3. C#编程(十)----------C#预处理器

    原文链接:http://blog.csdn.net/shanyongxu/article/details/46491757 C#中的预处理器指令 #IF 如果 C# 编译器遇到最后面跟有 #endif ...

  4. Harp – 内置常用预处理器的静态 Web 服务器

    Harp 是一个基于 Node.js 平台的静态 Web 服务器,内置流行的预处理器,支持把 Jade, Markdown, EJS, Less, Stylus, Sass, and CoffeeSc ...

  5. CSS预处理器实践之Sass、Less大比拼[转]

    什么是CSS预处理器? CSS可以让你做很多事情,但它毕竟是给浏览器认的东西,对开发者来说,Css缺乏很多特性,例如变量.常量以及一些编程语法,代码难易组织和维护.这时Css预处理器就应运而生了.Cs ...

  6. C#中的预处理器指令详解

    这篇文章主要介绍了C#中的预处理器指令详解,本文讲解了#define 和 #undef.#if.#elif.#else和#endif.#warning和#error.#region和#endregio ...

  7. C#中的预处理器指令

    C#中有许多名为“预处理器指令”的命令.这些命令从来不会转化为可执行代码中的命令,但会影响编译过程的各个方面. 例如,使用预处理器指令可以禁止编译器编译代码的某一部分.如果计划发布两个版本的代码,即基 ...

  8. CSS预处理器Sass(Scss)、Less、Stylus

    CSS 预处理编译器能让我成程序化其的方式编写CSS代码,可以引入CSS中没有的变量.条件.函数等特性,从而让代码更简单易维护,但一般按预处理器语法编写的代码无法直接在浏览器中运行,需用通过工具比如g ...

  9. Sass:一种CSS预处理器语言

    http://sass-lang.com/ Sass是一种CSS预处理器语言,通过编程方式生成CSS代码.因为可编程,所以操控灵活性自由度高,方便实现一些直接编写CSS代码较困难的代码. 同时,因为S ...

随机推荐

  1. 使用 python 查看谁没有交作业

    话说实验报告每天都要查人数,何不用程序实现 使用 python 查看谁没有交作业 version 1.0 程序嘛,肯定是可以改进的.使用该程序的前提是实验报告文件名中包含学号信息.将以上程序放在实验报 ...

  2. 家庭记账本app进度之ui相关概念控制ui界面与布局管理

    ui就是用户界面设计的意思. 首先是view,view相当于窗户上的玻璃. 1.android:id属性.android:id="@+id/user".他的id是user前面的@+ ...

  3. java文件中字母出现的次数和百分比

    主要是文件的读写.先在代码中导入文件.一行一行的进行数据的读入,通过“  ”空格对读入的信息进行分割,存入到数组里之后对于每一个单词的每一个字母进行区分存入相应的字母数组里.最后统计总的字母个数.应用 ...

  4. php-fpm cgi fast-cgi

    基础 在整个网站架构中,Web Server(如Apache)只是内容的分发者.举个栗子,如果客户端请求的是 index.html,那么Web Server会去文件系统中找到这个文件,发送给浏览器,这 ...

  5. java day04记录

    本文主要记录arr数组用法.count计算.arr倒排序技巧案例 package day4homework; import java.util.Scanner; /* 从键盘上输入10个整数,合法值位 ...

  6. 六、路由详细介绍之动态路由RIP(了解一下就行)

    动态路由分为距离矢量路由(RIP)和链路状态(OSPF和ISIS) 一.离矢量路由协议-RIP RIP协议现在基本上被淘汰. RIP动态路由协议工作原理,如上图: R12中有192.168.1.0和1 ...

  7. MAC 上brew 更新 出错

    在MAC上brew update的时候出现报错:Error: /usr/local must be writable! 错误,在该文章中也给出解决办法(sudo chown -R $(whoami) ...

  8. 今日写一篇散文 Textview settext 方法不能放入 int 参数 不然报错!

    Textview settext 方法不能放入 int 参数 不然报错!

  9. 给想学python但还没有接触过的你,python代码的书写规则,小白入门

    Python 文件结构 变量命名 注释 单行注释 多行注释 缩进 Python 文件结构 #!/usr/bin/env python3 # 指定python解释器 # -*- coding: utf- ...

  10. PHP-fpm 远程代码执行漏洞(CVE-2019-11043)复现

    简介 9 月 26 日,PHP 官方发布漏洞通告,其中指出:使用 Nginx + php-fpm 的服务器,在部分配置下,存在远程代码执行漏洞.并且该配置已被广泛使用,危害较大. 漏洞概述 Nginx ...