枚举集合

更新:2007 年 11 月

.NET Framework 提供枚举数作为循环访问一个集合的简单方法。枚举数只读取集合中的数据,无法用于修改基础集合。

有些语言提供一个隐藏直接使用枚举数的复杂性的语句。C# foreach 语句、C++ for each 语句和 Visual Basic For Each 语句使用枚举数。

关于枚举数

一个枚举数展平一个集合,以便可以按顺序访问成员。不同的集合类可能具有不同的序列。例如,ArrayList 的枚举数保留在集合中输入元素时的顺序,而 Hashtable 的枚举数根据元素的哈希代码显示元素。

每一枚举数都基于 IEnumerator 接口或 IEnumerator<T> 泛型接口,这两个接口要求以下成员:

  • Current 属性指向集合中的当前成员。

  • MoveNext 属性将枚举数移到集合中的下一成员。

  • Reset 属性将枚举数移回集合的开始处。Current 被定位于第一个元素的前面。Reset 在泛型 IEnumerator<T> 接口中不可用。

枚举数的行为

最初,枚举数被定位于集合中第一个元素的前面。Reset 还将枚举数返回到此位置。在此位置上,Current 为未定义。因此,您必须调用 MoveNext,以在读取 Current 的值之前将该枚举数提前到该集合的第一个元素。

Current 返回相同的对象,直到调用 MoveNextReset 为止。MoveNextCurrent 设置为下一个元素。

如果 MoveNext 超过集合的末尾,枚举数将被定位在集合中最后一个元素之后,而且 MoveNext 返回 false。枚举数处于这个位置时,随后对 MoveNext 的调用也会返回 false。如果对 MoveNext 的最后一次调用返回 false,则 Current 为未定义。

在非泛型集合中,您可以在调用 Reset 后调用 MoveNext,将枚举数移回集合的开始处。

在泛型集合中,您不能再将 Current 设置为集合的第一个元素;而须创建新的枚举数实例。

只要该集合保持不变,枚举数也就保持有效。如果对该集合进行了更改(例如添加、修改或删除了元素),该枚举数将失效(这一变化是不可逆转的),且其行为将变为未定义。

该枚举数不具有独占访问集合的权限;因此,枚举整个集合本质上不是一个线程安全的过程。若要确保枚举过程中的线程安全性,可以在整个枚举过程中锁定集合。若允许多个线程对集合执行读写操作,您必须实现自己的同步。

请参见

参考

IEnumerator

IEnumerator<T>

IDictionaryEnumerator

IEnumerable

IEnumerable<T>

其他资源

创建和操作集合