在C#中,如果一个类要使用foreach结构来实现迭代,就必须实现IEnumerable或IEnumerator接口。其中,IEnumerator接口定义了实现枚举器模式的方法IEnumerator.MoveNext()和IEnumerator.Reset()和成员属性IEnumerator.Count,而IEnumerable接口的唯一方法IEnumerable.GetEnumerator()仅用来返回一个IEnumerator对象,用来间接实现一个IEnumerator接口。
而泛型的IEnumerator<T>和IEnumerable<T>接口与普通类型的相似,它们是普通类型枚举器接口的泛化形式。但实现IEnumerable<T>接口,需要实现两个GetEnumerator,分别为IEnumerator IEnumerable.GetEnumerator()和IEnumerator<T> GetEnumerator()。
1、IEnumerator的实现
自己找例子看.....
2、IEnumerable的实现
(1)返回一个IEnumerator
自己找例子看.....
(2)使用yield return(yield break)语法
自己找例子看看.....
3、一种混合实现的结构
在一个类(如ClassName1)中实现IEnumerable接口,而在另一个类(如ClassName1Enumerator)中实现IEnumerator接口,并在ClassName1中的GetEnumerator()方法中,返回一个用ClassName1实例化的ClassName1Enumerator对象。
4、枚举器具体介绍
枚举器可用于读取集合中的数据,但不能用于修改基础集合。
最初,枚举器被定位于集合中第一个元素的前面。Reset 方法还将枚举器返回到此位置。在此位置,调用Current 属性会引发异常。因此,在读取Current 的值之前,必须先通过调用MoveNext 方法将枚举器前移到集合中的第一个元素。
在调用MoveNext 或Reset 之前,Current 返回同一对象。MoveNext 将Current 设置到下一个元素。
如果MoveNext 越过集合的末尾,则枚举器将放置在集合中最后一个元素的后面,而且MoveNext 返回false。当枚举器位于此位置时,对MoveNext 的后续调用也返回false。如果最后一次调用MoveNext 返回了false,则调用 Current 会引发异常。若要再次将Current 设置为集合的第一个元素,可以调用Reset,然后再调用MoveNext。
只要该集合保持不变,枚举器也就保持有效。如果对该集合进行了更改(例如添加、修改或删除元素),则该枚举数变为无效(这一变化是不可恢复的),并且下次调用MoveNext 或Reset 将引发InvalidOperationException。如果在MoveNext 和Current 之间修改了集合,则Current 会返回已将它设置为的元素,即使该枚举数已失效。
该枚举器不具有独占访问集合的权限;因此,枚举整个集合本质上不是一个线程安全的过程。即使集合已同步,其他线程仍可以修改集合,从而使枚举数引发异常。若要确保枚举过程中的线程安全性,可以在整个枚举期间锁定集合,或者捕获由其他线程进行的更改所导致的异常。
版权声明:本文为博主原创文章,未经博主允许不得转载。