.NET迭代器

      在.NET下,当我们在定义某个集合类型时,要在这个集合类型上面实现foreach迭代,需要进行实现IEnumerable,再进一步实现IEnumerator接口。

如MSDN上面的代码:

ContractedBlock.gif ExpandedBlockStart.gif View Code
 
   
1 using System;
2   using System.Collections;
3
4   public class Person
5 {
6 public Person( string fName, string lName)
7 {
8 this .firstName = fName;
9 this .lastName = lName;
10 }
11
12 public string firstName;
13 public string lastName;
14 }
15
16 public class People : IEnumerable
17 {
18 private Person[] _people;
19 public People(Person[] pArray)
20 {
21 _people = new Person[pArray.Length];
22
23 for ( int i = 0 ; i < pArray.Length; i ++ )
24 {
25 _people[i] = pArray[i];
26 }
27 }
28
29 public IEnumerator GetEnumerator()
30 {
31 return new PeopleEnum(_people);
32 }
33 }
34
35 public class PeopleEnum : IEnumerator
36 {
37 public Person[] _people;
38
39 // Enumerators are positioned before the first element
40 // until the first MoveNext() call.
41 int position = - 1 ;
42
43 public PeopleEnum(Person[] list)
44 {
45 _people = list;
46 }
47
48 public bool MoveNext()
49 {
50 position ++ ;
51 return (position < _people.Length);
52 }
53
54 public void Reset()
55 {
56 position = - 1 ;
57 }
58
59 public object Current
60 {
61 get
62 {
63 try
64 {
65 return _people[position];
66 }
67 catch (IndexOutOfRangeException)
68 {
69 throw new InvalidOperationException();
70 }
71 }
72 }
73 }
74
75 class App
76 {
77 static void Main()
78 {
79 Person[] peopleArray = new Person[ 3 ]
80 {
81 new Person( " John " , " Smith " ),
82 new Person( " Jim " , " Johnson " ),
83 new Person( " Sue " , " Rabon " ),
84 };
85
86 People peopleList = new People(peopleArray);
87 foreach (Person p in peopleList)
88 Console.WriteLine(p.firstName + " " + p.lastName);
89
90 }
91 }
92
93 /* This code produces output similar to the following:
94 *
95 * John Smith
96 * Jim Johnson
97 * Sue Rabon
98 *
99 */

这样的实现想必是有些麻烦。迭代器就是让我们的实现foreach的功能更加简便。先来看看MSDN上面关于迭代器的定义。

     迭代器是定义在结构或者类中,其定义形式可以是方法,get访问器,运算符。要求定义后的迭代器的返回类型必须是IEnumerable、IEnumerator、IEnumerable<T> 或 IEnumerator<T>。这四者之中的一个。通过定义迭代器,我们就可以实现对类,结构中的数据结构实现访问。而不必像上面一样,完全实现IEnumerable、IEnumerator接口。当编译器检测到迭代器时,它将自动生成 IEnumerableIEnumerable<T> 接口的 CurrentMoveNextDispose 方法。

     需要注意一点的是,在迭代器中引入了一个新的关键字:yield。迭代器代码使用 yield return 语句依次返回每个元素。yield break 将终止迭代。

下面是通过使用迭代器实现上面功能的代码:

方式1:

没有继承自IEnumerable

ContractedBlock.gif ExpandedBlockStart.gif View Code
 
   
1 public class People {
2 private Person[] _people;
3 public People(Person[] pArray)
4 {
5 _people = new Person[pArray.Length];
6
7 for ( int i = 0 ; i < pArray.Length; i ++ )
8 {
9 _people[i] = pArray[i];
10 }
11 }
12
13 public IEnumerable Test()
14 {
15 for ( int i = 0 ; i < _people.Length; i ++ )
16 {
17 yield return _people[i];
18 }
19 }
20
21 }

foreach访问方式:

ContractedBlock.gif ExpandedBlockStart.gif View Code
 
   
1 foreach (Person item in people.Test())
2 {
3 Console.WriteLine(item.firstName);
4 }

实现方式2:

继承自IEnumerable。

foreach访问方式:

ContractedBlock.gif ExpandedBlockStart.gif View Code
 
   
1 public class People :IEnumerable
2 {
3 private Person[] _people;
4 public People(Person[] pArray)
5 {
6 _people = new Person[pArray.Length];
7
8 for ( int i = 0 ; i < pArray.Length; i ++ )
9 {
10 _people[i] = pArray[i];
11 }
12 }
13
14 public IEnumerable Test()
15 {
16 for ( int i = 0 ; i < _people.Length; i ++ )
17 {
18 yield return _people[i];
19 }
20 }
21
22 public IEnumerator GetEnumerator()
23 {
24 for ( int i = 0 ; i < _people.Length; i ++ )
25 {
26 yield return _people[i];
27 }
28 }
29 }
ContractedBlock.gif ExpandedBlockStart.gif View Code
 
   
1 foreach (Person item in people)
2 {
3 Console.WriteLine(item.firstName);
4 }

转载于:https://www.cnblogs.com/wuxiaoqian726/archive/2011/02/24/1963466.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值