自定义一个可以使用foreach语句进行迭代的类(IEnumerable)

  在c#中,凡是实现了IEnumerable接口的数据类型都可以用foreach语句进行迭代访问。所以,我们要定义一个可以使用foreach进行迭代访问的类,就必须要实现IEnumerable接口。

 1 // 摘要:
 2 //     公开枚举器,该枚举器支持在非泛型集合上进行简单迭代。
 3 public interface IEnumerable
 4 {
 5     // 摘要:
 6     //     返回一个循环访问集合的枚举器。
 7     //
 8     // 返回结果:
 9     //     可用于循环访问集合的 System.Collections.IEnumerator 对象。
10     [DispId(-4)]
11     IEnumerator GetEnumerator();
12 }

  在IEnumerable中,只有一个GetEnumerator方法,而GetEnumerator返回一个IEnumerator对象,所以要看下IEnumerator的定义。

 1     // 摘要:
 2     //     支持对非泛型集合的简单迭代。
 3     public interface IEnumerator
 4     {
 5         // 摘要:
 6         //     获取集合中的当前元素。
 7         //
 8         // 返回结果:
 9         //     集合中的当前元素。
10         //
11         // 异常:
12         //   System.InvalidOperationException:
13         //     枚举器定位在该集合的第一个元素之前或最后一个元素之后。- 或 -在创建了枚举器后集合被修改了。
14         object Current { get; }
15 
16         // 摘要:
17         //     将枚举器推进到集合的下一个元素。
18         //
19         // 返回结果:
20         //     如果枚举器成功地推进到下一个元素,则为 true;如果枚举器越过集合的结尾,则为 false。
21         //
22         // 异常:
23         //   System.InvalidOperationException:
24         //     在创建了枚举器后集合被修改了。
25         bool MoveNext();
26         //
27         // 摘要:
28         //     将枚举器设置为其初始位置,该位置位于集合中第一个元素之前。
29         //
30         // 异常:
31         //   System.InvalidOperationException:
32         //     在创建了枚举器后集合被修改了。
33         void Reset();
34     }

  IEnumerator中有Current属性和MoveNet、Reset两个方法,所以要定义一个类来继承IEnumerator并实现这些方法属性。

  通过IEnumerable和IEnumerator定义可以看出要实现foreach迭代,我们要定义两个对象,一个实现接口IEnumerable,一个实现接口IEnumerator,IEnumerable中的GetEnumerator()看作IEnumerator object的factory method 也未尝不可。

 1 class CatArray : IEnumerable {
 2     private string[] cats = { "Kiky", "Mary", "Lily", "Garfield" };
 3     public IEnumerator GetEnumerator() {
 4         return new CatEnumerator(cats);
 5     }
 6 }
 7 class CatEnumerator : IEnumerator {
 8     private string[] _cats = null;
 9     public CatEnumerator(string[] cats) {
10         _cats = cats;
11     }
12     private int index = -1;
13     public object Current {
14         get { return _cats[index]; }
15     }
16     public bool MoveNext() {
17         if (++index < _cats.Length) {
18             return true;
19         } else {
20             return false;
21         }
22     }
23     public void Reset() {
24         index = -1;
25     }
26 }
27 private void Button_Click_3(object sender, RoutedEventArgs e) {
28     CatArray cats = new CatArray();
29     foreach (string cat in cats) {
30         tb3.Text += cat + "";
31     }
32 }

 

 

 

 

posted @ 2013-07-29 17:21  ╰→劉じ尛鶴  阅读(274)  评论(0编辑  收藏  举报