在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
会返回已将它设置为的元素,即使该枚举数已失效。
该枚举器不具有独占访问集合的权限;因此,枚举整个集合本质上不是一个线程安全的过程。
即使集合已同步,其他线程仍可以修改集合,从而使枚举数引发异常。
若要确保枚举过程中的线程安全性,可以在整个枚举期间锁定集合,或者捕获由其他线程进行的更改所导致的异常。