C#2.0 新特性探究(一) 模拟List和内置算法

C# 中的范型对于很多从 C++ 转过来的程序员来说,可以说是一个天大的喜讯。 hehe ,至少笔者对于这个新特性是充满了敬仰之情。

在 C#2.0 中,匿名方法、 IEnumerable 接口和匿名方法的合作,使很多的编程任务变得非常的简单,而且写出来的程序非常的优美。

比如,我们可以写出如下的代码:

List < Book > thelib = Library .getbooks();

List < Book > found = thelib.FindAll( delegate ( Book curbook)

{

if (curbook.isbn.StartsWith( "..." ))

return true ;

return false ;

});

foreach ( Book b in found)

Console .WriteLine(b.isbn);

这段程序非常简单的展示给我们需要查找的信息,代码也非常的直接易懂。内置的数据结构给了我们强大的算法支持,不过,能不能够为自定义的类定义类似的算法呢?

比如,如果我有一个自定义的 Library 类并没有使用 List

  1<book> 存储数据,而是使用某种自定义的数据结构,我能不能也让用户使用类似的语法,忽略存储细节的使用匿名委托来实现特定的算法呢? 
  2
  3答案当然是肯定的,而且在  C#  中实现这样的功能是非常的简单。 
  4
  5首先让我们看看  FindAll  中用到的匿名委托的原型 
  6
  7public  delegate  bool  Predicate  <t>(T obj); 
  8
  9很明显的,上面的代码等于注册了一个搜索的回调,而在  List  内部定义了某种遍历的机制,从而实现了一个漂亮的算法结构  Closure  。 
 10
 11看到了这些,我们就可以定义自己的算法结构了,首先,我定义了一个如下的类 
 12
 13public  class  MyVec  <t>
 14
 15{ 
 16
 17public  static  MyVec  <t> operator  +(  MyVec  <t> a, T b) 
 18
 19{ 
 20
 21a._list.Add(b); 
 22
 23return  a; 
 24
 25} 
 26
 27public  override  string  ToString() 
 28
 29{ 
 30
 31StringBuilder  builder =  new  StringBuilder  (); 
 32
 33foreach  (T a  in  _list) 
 34
 35{ 
 36
 37builder.Append(a.ToString()); 
 38
 39builder.Append(  ","  ); 
 40
 41} 
 42
 43string  ret = builder.Remove(builder.Length - 1, 1).ToString(); 
 44
 45return  ret; 
 46
 47} 
 48
 49public  MyVec  <t> findAll(  Predicate  <t> act) 
 50
 51{ 
 52
 53MyVec  <t> t2 =  new  MyVec  <t>(); 
 54
 55foreach  (T i  in  _list) 
 56
 57{ 
 58
 59if  (act(i)) 
 60
 61t2._list.Add(i); 
 62
 63} 
 64
 65return  t2; 
 66
 67} 
 68
 69// this is the inner object 
 70
 71private  List  <t> _list =  new  List  <t>(); 
 72
 73} 
 74
 75这个类中包含了一个的  List<t> 结构,主要是为了证实我们的想法是否可行,事实上,任何一个可以支持  foreach  遍历的结构都可以作为内置的数据存储对象,我们会在后面的例子中给出一个更加复杂的实现。 
 76
 77下面是用于测试这个实验类的代码: 
 78
 79static  void  Main  (  string  [] args) 
 80
 81{ 
 82
 83MyVec  &lt; int  &gt; a =  new  MyVec  &lt; int  &gt;(); 
 84
 85a += 12; 
 86
 87a += 15; 
 88
 89a += 32; 
 90
 91MyVec  &lt; int  &gt; b = a.findAll(  delegate  (  int  x) 
 92
 93{  if  (x &gt; 20)  return  true  ;  return  false  ; } 
 94
 95); 
 96
 97Console  .WriteLine(  "vection original"  ); 
 98
 99Console  .WriteLine(a.ToString()); 
100
101Console  .WriteLine(  "vection found"  ); 
102
103Console  .WriteLine(b.ToString()); 
104
105Console  .ReadLine(); 
106
107} 
108
109编译,执行,程序输出: 
110
111vection original 
112
11312,15,32 
114
115vection found 
116
11732 
118
119和我们预期的完全相同。很明显的,  List  内部的算法与我们预期的基本相同。 
120
121Predicate  <t> 仅仅是为了仿照系统的实现而采用的一个委托,事实上可以使用自己定义的任何委托作为回调的函数体。 
122
123通过使用  IEnumberable  接口,可以实现对任意结构的遍历,从而对任何数据结构定义强大的算法支持。</t></t></t></t></t></t></t></t></t></t></t></t></book>
Published At
Categories with Web编程
Tagged with
comments powered by Disqus