c#语言中提供了一种集合的访问方式:foreach。这是一种自动确定边界的单向的访问方式。这次来谈一谈如何实现自定义类中的foreach功能。
        比如现在有一个类Forest 的实例MyForest,其中有一个Tree的数组,Tree是我们自己创建的另一个类.。

1  public class Forest
2     {
3         private Tree[] trees;
4             .
5             .
6             .
7     }

假设有一个类Forest 的实例MyForest, 也许我们希望写这样的代码:

foreach(Tree tree in MyForest)
{
     DoSomething(tree);
}

而不是:

1 for(int i=0;i<MyForest.Trees.Lenth;i++)
2 {
3     Tree tree=MyForest.Tree[i];
4     DoSomething(tree);
5 }

显然,使用foreach比用下标来循环更加的直观,对服务类的内部信息的要求也会降低(不要求针对trees的属性),如何在Forest中实现foreach功能呢?
   
其实,只要是从IEnumerable接口继承下来的类,只要正确实现了接口中的public IEnumerator GetEnumerator()方法,就可以实现foreach,可以看出,这个方法返回的是一个IEnumerator对象,实际上,这个IEnumerator正是实现foreach的核心。先给出代码:

 1  public class Forest:IEnumerable
 2     {
 3         private Tree[] trees;
 4         public Forest(Tree[] someTrees)
 5         {
 6             this.trees=someTrees;
 7         }
 8 
 9 
10         public IEnumerator GetEnumerator()
11         {
12             return new ForestEnumerator(this);
13         }
14 
15         private class ForestEnumerator:IEnumerator
16         {
17             private int position;
18             private Forest forest;
19             public ForestEnumerator(Forest aforest)
20             {
21                 this.forest=aforest;
22                 this.position=-1;
23             }
24 
25             public object Current
26             {
27                getreturn this.forest.trees[this.position];}
28             }
29 
30             public bool MoveNext()
31             {
32                 if(this.position<this.forest.trees.Length-1)
33                 {
34                     this.position++;
35                     return true;
36                 }
37 
38                 return false;
39             }
40 
41             public void Reset()
42             {
43                 this.position=-1;
44             }
45         }
46 }

 

 1  public class Tree
 2     {
 3         private string name;
 4         public Tree(string aname)
 5         {
 6             this.name = aname;
 7         }
 8 
 9         public override string ToString()
10         {
11             return this.name;
12         }
13     }

代码中的10-13行既是GetEnumerator函数的实现,返回一个ForestEnumerator对象,这是一个内部类ForestEnumerator的对象,这个内部类决定了如何执行foreach,可以看见,这个内部类是从IEnumerator继承的,其中有一个属性:Current,两个函数:MoveNext,Reset需要自己实现,这三个函数就是负责foreach执行的,顾名思义Current表示目前对集合的访问进行到何处,MoveNext确定是否还能向下一个元素访问,Reset将访问点移动到集合的首部,准备下一次的访问。至于其中的集合是什么,由你自己决定。其中的变量position是一个游标,指示当前对集合的访问位置。

讲的还算清楚吧,具体的看代码吧。

1  static void Main(string[] args)
2         {
3 
4             Tree[] trees ={new Tree("apple"),new Tree("pine"),new Tree("no leaves") };
5             Forest forest = new Forest(trees);
6             foreach (Tree tree in forest)
7                 Console.WriteLine( tree.ToString());
8         }

 

我想我是被msdn给骗了,两年以后我才知道。其实根本不用这么麻烦,继承一个IEnumerable接口就行了。

Code


posted on 2005-12-12 21:46  死于青春  阅读(729)  评论(2编辑  收藏  举报