在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
一、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
1 using System;
2 using System.Collections.Generic; 3 using System.IO; 4 using System.Text; 5 using System.Text.RegularExpressions; 6 7 namespace Orc.Util.Csmacro 8 { 9 class Program 10 { 11 static Regex includeReg = new Regex("#region\\s+include.+\\s+#endregion"); 12 static Regex mixinReg = new Regex("(?<=#region\\s+mixin\\s)[\\s|\\S]+(?=#endregion)"); 13 14 /// <summary> 15 /// Csmacro [dir|filePath] 16 /// 17 /// 语法: 18 /// #region include "" 19 /// #endregion 20 /// 21 /// </summary> 22 /// <param name="args"></param> 23 static void Main(string[] args) 24 { 25 if (args.Length != 1) 26 { 27 PrintHelp(); 28 return; 29 } 30 31 String filePath = args[0]; 32 33 Path.GetDirectoryName(filePath); 34 String dirName = Path.GetDirectoryName(filePath); 35 #if DEBUG 36 Console.WriteLine("dir:" + dirName); 37 #endif 38 String fileName = Path.GetFileName(filePath); 39 #if DEBUG 40 Console.WriteLine("file:" + fileName); 41 #endif 42 43 if (String.IsNullOrEmpty(fileName)) 44 { 45 Csmacro(new DirectoryInfo(dirName)); 46 } 47 else 48 { 49 if (fileName.EndsWith(".cs") == false) 50 { 51 Console.WriteLine("Csmacro只能处理后缀为.cs的源程序."); 52 } 53 else 54 { 55 Csmacro(new FileInfo(fileName)); 56 } 57 } 58 59 Console.WriteLine("[Csmacro]:处理完毕."); 60 61 #if DEBUG 62 Console.ReadKey(); 63 #endif 64 } 65 66 static void Csmacro(DirectoryInfo di) 67 { 68 Console.WriteLine("[Csmacro]:进入目录" + di.FullName); 69 70 foreach (FileInfo fi in di.GetFiles("*.cs", SearchOption.AllDirectories)) 71 { 72 Csmacro(fi); 73 } 74 } 75 76 static void Csmacro(FileInfo fi) 77 { 78 String fullName = fi.FullName; 79 if (fi.Exists == false) 80 { 81 Console.WriteLine("[Csmacro]:文件不存在-" + fullName); 82 } 83 else if (fullName.EndsWith("_Csmacro.cs")) 84 { 85 return; 86 } 87 else 88 { 89 String text = File.ReadAllText(fullName); 90 91 DirectoryInfo parrentDirInfo = fi.Directory; 92 93 MatchCollection mc = includeReg.Matches(text); 94 if (mc == null || mc.Count == 0) return; 95 else 96 { 97 Console.WriteLine("[Csmacro]:处理文件" + fullName); 98 99 StringBuilder sb = new StringBuilder(); 100 Match first = mc[0]; 101 Match last = mc[mc.Count - 1]; 102 103 sb.Append(text.Substring(0, first.Index)); 104 105 foreach (Match m in mc) 106 { 107 String tmp = Csmacro(parrentDirInfo, m.Value); 108 sb.Append(tmp); 109 } 110 111 Int32 lastEnd = last.Index + last.Length; 112 if (lastEnd < text.Length) 113 { 114 sb.Append(text.Substring(lastEnd)); 115 } 116 String newName = fullName.Substring(0, fullName.Length - 3) + "_Csmacro.cs"; 117 if (File.Exists(newName)) 118 { 119 Console.WriteLine("[Csmacro]:删除旧文件" + newName); 120 } 121 File.WriteAllText(newName, sb.ToString()); 122 Console.WriteLine("[Csmacro]:生成文件" + newName); 123 } 124 } 125 } 126 127 static String Csmacro(DirectoryInfo currentDirInfo, String text) 128 { 129 String outfilePath = text.Replace("#region", String.Empty).Replace("#endregion", String.Empty).Replace("include",String.Empty).Replace("\"",String.Empty).Trim(); 130 try 131 { 132 if (Path.IsPathRooted(outfilePath) == false) 133 { 134 outfilePath = currentDirInfo.FullName + @"\" + outfilePath; 135 } 136 FileInfo fi = new FileInfo(outfilePath); 137 if (fi.Exists == false) 138 { 139 Console.WriteLine("[Csmacro]:文件" + fi.FullName + "不存在."); 140 return text; 141 } 142 else 143 { 144 return GetMixinCode(File.ReadAllText(fi.FullName)); 145 } 146 } 147 catch (Exception ex) 148 { 149 Console.WriteLine("[Csmacro]:出现错误(" + outfilePath + ")-" + ex.Message); 150 } 151 finally 152 { 153 } 154 return text; 155 } 156 157 static String GetMixinCode(String txt) 158 { 159 Match m = mixinReg.Match(txt); 160 if (m.Success == true) 161 { 162 return m.Value; 163 } 164 else return String.Empty; 165 } 166 167 static void PrintHelp() 168 { 169 Console.WriteLine("Csmacro [dir|filePath]"); 170 } 171 } 172 } 173 174
编译之后,放在系统路径下(或放入任一在系统路径下的目录)。然后,在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 专题导读
热门推荐
热门话题
阅读排行榜
|
请发表评论