欧美V国产V亚洲V日韩九九_国产偷V国产偷V亚洲高清_蜜桃精品免费久久久久影院_亚洲男同志Gay 片可播放

在《》文中,指(zhi)出了(le)C#泛型的(de)局限性(xing)(xing),為了(le)突破(po)這個局限性(xing)(xing),我們(men)需要模板編(bian)(bian)程(cheng)。但(dan)是(shi),C#語法以(yi)及IDE均不(bu)支持C#模板編(bian)(bian)程(cheng),怎么(me)辦呢?自己動手(shou),豐衣足食(shi),編(bian)(bian)寫(xie)自己的(de)C#預處理器。

一、C#預處理機制設計

問題的(de)關(guan)鍵就(jiu)是在(zai)C#的(de)源文件中引入include機制,設計下面的(de)語法:

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

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

 

例子:假設A.cs需要引用B.cs中(zhong)的代碼。A文件(jian)內容(rong)為:

XXX

#region include "B.cs"
#endregion

XXX

B.cs 文件(jian)內(nei)容為:

YYY

#region mixin

MMM

#endregion

ZZZ

運行(xing)預處理器,對A文件進行(xing)處理,生成第三個文件A_.cs:

XXX

MMM

XXX

二、實現

編寫預(yu)處理器(qi):Csmacro.exe[](意思是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      &nbsp;      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          &nbsp;  Console.WriteLine("file:" + fileName);
 41 #endif 
 42 
 43    &nbsp;        if (String.IsNullOrEmpty(fileName))
 44             {
 45      &nbsp;          Csmacro(new DirectoryInfo(dirName));
 46             }
 47  &nbsp;&nbsp;         else
 48             {
 49 &nbsp;        &nbsp;      if (fileName.EndsWith(".cs"== false)
 50                 {
 51        &nbsp;            Console.WriteLine("Csmacro只(zhi)能(neng)處理(li)后綴為.cs的(de)源(yuan)程序.");
 52                 }
 53    &nbsp;            else
 54                 {
 55                &nbsp;    Csmacro(new FileInfo(fileName));
 56                 }
 57             } 
 58 
 59        &nbsp;    Console.WriteLine("[Csmacro]:處理完畢."); 
 60 
 61 #if DEBUG
 62             Console.ReadKey();
 63 #endif
 64         } 
 65 
 66         static void Csmacro(DirectoryInfo di)
 67         {
 68         &nbsp;   Console.WriteLine("[Csmacro]:進(jin)入目錄" + 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           &nbsp; String fullName ;= fi.FullName;
 79             if (fi.Exists == false)
 80             {
 81     &nbsp;           Console.WriteLine("[Csmacro]:文(wen)件不存(cun)在-" + fullName);
 82             }
 83            &nbsp;else if (fullName.EndsWith("_Csmacro.cs"))
 84             {
 85 &nbsp;               return;
 86             }
 87             else
 88             {
 89    &nbsp;            String text = File.ReadAllText(fullName); 
 90 
 91           &nbsp;     DirectoryInfo parrentDirInfo = fi.Directory; 
 92 
 93              &nbsp;  MatchCollection mc = includeReg.Matches(text);
 94            &nbsp;    if (mc == null || mc.Count == 0return;
 95        ;         else
 96                 {
 97  &nbsp;                  Console.WriteLine("[Csmacro]:處(chu)理(li)文件" + fullName); 
 98 
 99          &nbsp;          StringBuilder sb = new StringBuilder();
100  &nbsp;                  Match first = mc[0];
101     &nbsp;       ;        Match last = mc[mc.Count - 1]; 
102 
103                     sb.Append(text.Substring(0, first.Index)); 
104 
105            &nbsp;        foreach (Match m in mc)
106                     {
107      &nbsp;                  String tmp = Csmacro(parrentDirInfo, m.Value);
108                         sb.Append(tmp);
109                     } 
110 
111                     Int32 lastEnd = last.Index + last.Length;
112     &nbsp;             &nbsp; if (lastEnd < text.Length)
113                     {
114                         sb.Append(text.Substring(lastEnd));
115                     }
116    &nbsp;         &nbsp;      String newName = fullName.Substring(0, fullName.Length - 3+ "_Csmacro.cs";
117                     if (File.Exists(newName))
118                     {
119                &nbsp;        Console.WriteLine("[Csmacro]:刪除舊(jiu)文件" + newName);
120                     }
121                     File.WriteAllText(newName, sb.ToString());
122         &nbsp;       &nbsp;   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 &nbsp;   &nbsp;       try
131             {
132    &nbsp;            if (Path.IsPathRooted(outfilePath) == false)
133                 {
134             &nbsp;       outfilePath = currentDirInfo.FullName + @"\" + outfilePath;
135                 }
136                &nbsp;FileInfo fi = new FileInfo(outfilePath);
137  &nbsp;             &nbsp;if (fi.Exists == false)
138                 {
139             &nbsp;       Console.WriteLine("[Csmacro]:文件(jian)" + fi.FullName + "不存(cun)在.");
140  &nbsp;                ;  return text;
141                 }
142      &nbsp;          else
143                 {
144                     return GetMixinCode(File.ReadAllText(fi.FullName));
145                 }
146             }
147      &nbsp;      catch (Exception ex)
148             {
149       &nbsp;        &nbsp;Console.WriteLine("[Csmacro]:出現錯(cuo)誤(wu)(" + outfilePath + ")-" + ex.Message);
150             }
151        &nbsp;&nbsp;   finally
152             {
153             }
154             ;return text;
155         } 
156 
157         static String GetMixinCode(String txt)
158         {
159            &nbsp;Match m = mixinReg.Match(txt);
160     &nbsp;&nbsp;      if (m.Success == true)
161             {
162      &nbsp;          return m.Value;
163             }
164             else return String.Empty;
165         } 
166 
167         static void PrintHelp()
168         {
169      &nbsp;      Console.WriteLine("Csmacro [dir|filePath]");
170         }
171     }
172 }
173 
174 

 

編(bian)譯(yi)之(zhi)(zhi)后(hou)(hou),放在(zai)系(xi)統路徑下(或放入任一在(zai)系(xi)統路徑下的(de)(de)目(mu)錄)。然(ran)后(hou)(hou),在(zai)VS的(de)(de)項(xiang)目(mu)屬性(xing)的(de)(de)Build Events的(de)(de)Pre-build event command line中寫(xie)入“Csmacro.exe $(ProjectDir)”,即可(ke)在(zai)編(bian)譯(yi)項(xiang)目(mu)之(zhi)(zhi)前,對$(ProjectDir)目(mu)錄下的(de)(de)所有(you)cs程序進行預(yu)處理。

Csmacro.exe 對于(yu)包含(han)#region include <path> #endregion代(dai)碼的程(cheng)序xx.cs,預處理生成名(ming)為 xx_Csmacro.cs的文(wen)件(jian);對于(yu)文(wen)件(jian)名(ming)以(yi)"Csmacro.cs”結(jie)尾(wei)的文(wen)件(jian),則(ze)不進行任(ren)何(he)處理。

使用時要注意:

(1)#region include <path> 與 #endregion 之間不能有任何代碼(ma);

(2)#region mixin 與 #endgion 之間不能有其它(ta)的region

(3)不支持多級(ji)引(yin)用(yong)

三、示例

下面,以《》文尾的例(li)子說明怎樣編寫(xie)C#模板程序:

(1)建(jian)立一個模板類 FilterHelper_Template.cs ,編譯通過:

FilterHelper_Template.cs
 1 using TPixel = System.Byte; 
 2 using TCache = System.Int32; 
 3 using TKernel = System.Int32; 
 4 
 5 using System; 
 6 using System.Collections.Generic; 
 7 using System.Text; 
 8 
 9 namespace Orc.SmartImage.Hidden 
10 
11     static class FilterHelper_Template 
12     { 
13         #region mixin 
14 
15         // 本算法是錯誤的,只為說明C#模板程序的使用。 
16         public unsafe static UnmanagedImage<TPixel> Filter(this UnmanagedImage<TPixel> src, FilterKernel<TKernel> filter) 
17         { 
18       ;    ;  TKernel* kernel = stackalloc TKernel[filter.Length]; 
19 
20      &nbsp;      Int32 srcWidth = src.Width; 
21             Int32 srcHeight = src.Height; 
22    &nbsp;        Int32 kWidth = filter.Width; 
23             Int32&nbsp;kHeight = filter.Height; 
24 
25   ;         &nbsp;TPixel* start = (TPixel*)src.StartIntPtr; 
26        &nbsp; &nbsp;  TPixel* lineStart = start; 
27    &nbsp;     ;   TPixel* pStart = start; 
28  &nbsp;        &nbsp; TPixel* pTemStart = pStart; 
29       &nbsp;     TPixel* pT; 
30    &nbsp;&nbsp;       TKernel* pK; 
31 
32         &nbsp;   for (int c = 0; c < srcWidth; c++
33             { 
34   ;            &nbsp; for (int r = 0; r < srcHeight; r++
35                 { 
36       &nbsp;             pTemStart = pStart; 
37      ;              &nbsp;pK = kernel; 
38 
39                     Int32 val = 0
40                     for (int kc = 0; kc < kWidth; kc++
41                     { 
42        &nbsp;                pT = pStart; 
43                      &nbsp;&nbsp; for (int kr = 0; kr < kHeight; kr++
44                         { 
45         &nbsp;      &nbsp;            val += *pK * *pT; 
46                             pT++
47        &nbsp;       &nbsp;            pK++
48                         } 
49 
50    ;         &nbsp;           pStart += srcWidth; 
51                     } 
52 
53        ;             pStart = pTemStart; 
54              &nbsp;&nbsp;     pStart++
55                 } 
56 
57            ;     lineStart += srcWidth; 
58              &nbsp;  pStart = lineStart; 
59             } 
60 &nbsp;      &nbsp;    return null
61         } 
62         #endregion 
63     } 
64 }
65 
66 

 這里(li),我使用了命名(ming)(ming)空間(jian)Hidden,意(yi)思是(shi)這個命名(ming)(ming)空間(jian)不想讓外部(bu)使用,因為它(ta)是(shi)模(mo)板類。

 

(2)編寫(xie)實(shi)例化模(mo)板類 ImageU8FilterHelper.cs

ImageU8FilterHelper.cs
 1 using System; 
 2 using System.Collections.Generic; 
 3 using System.Text; 
 4 
 5 namespace Orc.SmartImage 
 6 
 7     using TPixel = System.Byte; 
 8     using TCache = System.Int32; 
 9     using TKernel = System.Int32; 
10 
11     public static partial class ImageU8FilterHelper 
12     { 
13         #region include "FilterHelper_Template.cs"&nbsp;
14         #endregion 
15     } 
16 }

注意(yi):這里使用 partial class 是為(wei)了使代(dai)碼與預處理器生成的(de)代(dai)碼共(gong)存,不產生編譯(yi)錯誤。

 

(3)編(bian)譯(yi)項目,可以發現(xian),預處理器自動生成(cheng)了代碼文件ImageU8FilterHelper_Csmacro.cs,且編(bian)譯(yi)通過:

ImageU8FilterHelper_Csmacro.cs
 1 using System; 
 2 using System.Collections.Generic; 
 3 using System.Text; 
 4 
 5 namespace Orc.SmartImage 
 6 
 7     using TPixel = System.Byte; 
 8     using TCache = System.Int32; 
 9     using TKernel = System.Int32; 
10 
11     public static partial class ImageU8FilterHelper 
12     {
13 
14         // 本(ben)算法(fa)是錯誤的,只為說明C#模板程序的使用(yong)。 
15         public unsafe static UnmanagedImage<TPixel> Filter(this UnmanagedImage<TPixel> src, FilterKernel<TKernel> filter) 
16         { 
17 &nbsp;           TKernel* kernel = stackalloc TKernel[filter.Length]; 
18 
19             Int32 srcWidth = src.Width; 
20      &nbsp; &nbsp;    Int32 srcHeight = src.Height; 
21           &nbsp; Int32 kWidth = filter.Width; 
22       &nbsp;     Int32 kHeight = filter.Height; 
23 
24    &nbsp;       &nbsp;TPixel* start = (TPixel*)src.StartIntPtr; 
25             TPixel* lineStart = start; 
26      ;       TPixel* pStart = start; 
27      &nbsp;      TPixel* pTemStart = pStart; 
28         &nbsp;   TPixel* pT; 
29     &nbsp;       TKernel* pK; 
30 
31        &nbsp;    for (int c = 0; c < srcWidth; c++
32             { 
33  &nbsp;       ;       for (int r = 0; r < srcHeight; r++
34                 { 
35         &nbsp;           pTemStart = pStart; 
36     &nbsp;              &nbsp;pK = kernel; 
37 
38     &nbsp;              &nbsp;Int32 val = 0
39                     for (int kc = 0; kc < kWidth; kc++
40                     { 
41            &nbsp;   &nbsp;        pT = pStart; 
42                      &nbsp;  for (int kr = 0; kr < kHeight; kr++
43                         { 
44                          ;   val += *pK * *pT; 
45     &nbsp;                &nbsp;      pT++
46                             pK++
47                         } 
48 
49                         pStart += srcWidth; 
50                     } 
51 
52                     pStart = pTemStart; 
53    ;                 pStart++
54                 } 
55 
56                 lineStart += srcWidth; 
57              &nbsp;  pStart = lineStart; 
58             } 
59   ;          return null
60         } 
61     } 
62 }
63 
64 

四、小結

這樣一(yi)(yi)來(lai),C#模(mo)板(ban)類(lei)使(shi)用(yong)就方便了(le)很多,不必手(shou)動(dong)去處理模(mo)板(ban)類(lei)的復制和粘(zhan)帖(tie)。雖(sui)然(ran)仍沒有C++模(mo)板(ban)使(shi)用(yong)那么自然(ran),畢竟(jing)又近了(le)一(yi)(yi)步。:P