C#模板编程(2): 编写C#预处理器,让模板来的再自然一点
2010-09-30 22:42:25 来源:WEB开发网这里,我使用了命名空间Hidden,意思是这个命名空间不想让外部使用,因为它是模板类。
(2)编写实例化模板类 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"
14 #endregion
15 }
16 }
注意:这里使用 partial class 是为了使代码与预处理器生成的代码共存,不产生编译错误。
(3)编译项目,可以发现,预处理器自动生成了代码文件ImageU8FilterHelper_Csmacro.cs,且编译通过:
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 // 本算法是错误的,只为说明C#模板程序的使用。
15 public unsafe static UnmanagedImage<TPixel> Filter(this UnmanagedImage<TPixel> src, FilterKernel<TKernel> filter)
16 {
17 TKernel* kernel = stackalloc TKernel[filter.Length];
18
19 Int32 srcWidth = src.Width;
20 Int32 srcHeight = src.Height;
21 Int32 kWidth = filter.Width;
22 Int32 kHeight = filter.Height;
23
24 TPixel* start = (TPixel*)src.StartIntPtr;
25 TPixel* lineStart = start;
26 TPixel* pStart = start;
27 TPixel* pTemStart = pStart;
28 TPixel* pT;
29 TKernel* pK;
30
31 for (int c = 0; c < srcWidth; c++)
32 {
33 for (int r = 0; r < srcHeight; r++)
34 {
35 pTemStart = pStart;
36 pK = kernel;
37
38 Int32 val = 0;
39 for (int kc = 0; kc < kWidth; kc++)
40 {
41 pT = pStart;
42 for (int kr = 0; kr < kHeight; kr++)
43 {
44 val += *pK * *pT;
45 pT++;
46 pK++;
47 }
48
49 pStart += srcWidth;
50 }
51
52 pStart = pTemStart;
53 pStart++;
54 }
55
56 lineStart += srcWidth;
57 pStart = lineStart;
58 }
59 return null;
60 }
61 }
62 }
63
64
四、小结
这样一来,C#模板类使用就方便了很多,不必手动去处理模板类的复制和粘帖。虽然仍没有C++模板使用那么自然,毕竟又近了一步。
更多精彩
赞助商链接