数组可以被foreach语句遍历数组中的元素,原因是数组可以按需提供一个叫做枚举数(enumerator)的对象.枚举数可以依次返回请求的数组的元素.
对于有枚举数的类型而言,必须有一个方法来获取它们.在.NET中获取一个对象枚举数的标准用法是调用对象的GetEnumerator方法.实现GetEnumerator方法的类型叫做可枚举类型(enumerable),数组就是可枚举类型.
要注意枚举数(enumerator)和可枚举类型(enumerable)的区别和联系.
枚举数是可以依次返回集合项的类对象,可枚举类型是带有GetEnumerator方法的类型,它返回枚举数.
当foreach被用来遍历可枚举类型时,它就会执行如下的行为:
1,通过调用GetEnumerator方法获取对象的枚举数.
2,从枚举数中请求每一项并且把它作为迭代变量,代码可以读但不可以改变.
枚举数共有3种,可以用以下方式来实现枚举数:
1 IEnumerator/IEnumerable接口 ,叫做非泛型接口形式.
2 IEnumerator<T>/IEnumerable<T>接口, 叫做泛型接口形式.
3 不使用接口形式.
IEnumerator接口
IEnumerator接口包含3个函数成员:Current,MoveNext,Reset
Current返回序列中当前项的属性,它是一个只读属性.返回object类型的引用,所以可以返回任何类型.
MoveNext是把枚举数位置前进到集合的下一项的方法,它返回布尔值,指示新位置是有效位置还是已经超过了序列的尾部.如果是已经到达了尾部,则返回false.
Reset方法把位置重置为原始状态.
查看下面的代码:
int[] MyArray = { 10, 11, 12, 13 }; //创建数组
IEnumerator ie = MyArray.GetEnumerator(); //获取枚举数
while (ie.MoveNext()) //移到下一项
Console.WriteLine((int)ie.Current); //获取当前项并输入
枚举数的初始位置是-1,所以要想获取第一个元素就必须执行MoveNext()方法.
上面的代码就是调用枚举数的Current和MoveNext成员函数手工地遍历数组中的元素.
或者可以直接使用foreach直接获取:
foreach(int i in MyArray)
Console.WriteLine(i);
下面列出一个颜色名数组的枚举数类:
using System.Collections;
class ColorEnumerator : IEnumerator
{
private string[] Colors;
private int Position = -1;
public object Current
{
get
{
if (Position == -1)
throw new InvalidOperationException();
if (Position == Colors.Length)
throw new InvalidOperationException(); ;
return Colors[Position];
}
}
public bool MoveNext()
{
if (Position < Colors.Length - 1)
{
Position ++;
return true;
}
else
return false;
}
public void Reset()
{
Position = -1;
}
public ColorEnumerator(string[] theColors) //构造函数
{
Colors = new string[theColors.Length];
for (int i = 0; i < theColors.Length - 1; i++)
Colors[i] = theColors[i];
}
}
以上代码就构造了一个完整的枚举数类型.下面生成对象返回枚举数.
class Program
{
static void Main()
{
ColorEnumerator ce = new ColorEnumerator(new string[]{"yellow","red","white","black"});
while (ce.MoveNext())
Console.WriteLine((string)(ce.Current));
Console.ReadKey();
}
}
如果要用foreach来遍历枚举数,需要再定义一个可枚举类型的类,这个类要实现IEnumerable接口的功能.
public interface IEnumerable
{
IEnumerator GetEnumerator();
}
class MyEnumerable : IEnumerable //定义一个可枚举类型的类
{
string[] MyColor = new string[] { "yellow", "red", "black", "white" };
public IEnumerator GetEnumerator() //实现接口
{
return new ColorEnumerator(MyColor); //返回一个枚举数的对象
}
}
现在就可以使用foreach来遍历可枚举类型对象的所有元素了.
class Program
{
static void Main()
{
MyEnumerable me = new MyEnumerable();
foreach (string i in me)
Console.WriteLine(i);
Console.ReadKey();
}
}
总结一下,如果想遍历一个对象中的所有元素,可以把对象设为枚举数类型(实现IEnumerator接口)和可枚举的类类型(实现IEnumerable接口),前者需要实现IEnumerator接口的Current,MoveNext和Rest成员函数,后者需要实现IEnumerable接口的GetEnumerator成员函数,由于GetEnumerator返回的是IEnumerator对象,所以还要建立一个派生于IEnumerator的枚举数类,在这个类中实现Current,MoveNext和Reset成员函数.派生于IEnumerable的类可以使用foreach代码来遍历对象中的全部元素.
分享到:
相关推荐
枚举类型的实例可以通过枚举器(enumerator)访问,例如`Colors.Red`。同时,枚举值可以通过`.ToString()`方法转换为字符串,或者通过`Enum.Parse()`和`Enum.TryParse()`方法将字符串转换回枚举值。 五、枚举与其他...
C#中可枚举类型详解 C# 中的可枚举类型是指实现了 IEnumerable 和 IEnumerator 接口的类型,这些类型可以被 foreach 循环迭代。可枚举类型的主要特点是可以枚举一个集合中的数据项,例如数组、列表、哈希表等。 ...
面向对象程序设计中的枚举集合是.NET框架中的一个重要概念,主要涉及到枚举器(Enumerator)和可枚举类型(Enumerable)。这些概念对于高效地遍历和处理数据集合至关重要。 首先,枚举集合中的元素通常使用`foreach...
二维或三维Reed-Solomon码的完全权枚举数_The complete weight enumerator of the Reed-Solomon code with dimension two or three.pdf
在这里,`identifier` 是枚举类型的别名,`enumerator_list` 是一系列用逗号分隔的枚举常量,每个枚举常量默认从0开始按顺序递增。例如: ```c enum weeks {SUN, MON, TUE, WED, THU, FRI, SAT}; ``` 在这个例子中...
枚举类型在编程中非常有用,因为它可以提高代码的可读性和可维护性,使程序员能够使用有意义的标识符来代替难以记忆的数字。 ### 枚举类型的基本语法 枚举类型的声明格式如下: ```c enum identifier { ...
枚举器(Enumerator)在C#编程中是一个关键的概念,它是.NET框架中实现迭代的关键工具。这个概念在处理集合和数组等数据结构时尤为重要,尤其是当你需要遍历这些集合而无需暴露其内部实现细节时。`foreach`循环是与...
其中,`identifier`是枚举类型的名称,`enumerator_list`是枚举常量的列表,它们默认从0开始按顺序递增。 2. 自增操作符`++`: 自增操作符`++`用于增加变量的值。在C语言中,`++`有前缀和后缀两种形式。前缀形式`...
一个类型如果实现了GetEnumerator方法,那么它就被认为是可枚举类型(enumerable)。例如,C#中的所有数组都是System.Array类的实例,Array类实现了System.Collections.IEnumerable接口,这个接口定义了一个...
C#枚举可以基于特定的基础类型(如int, byte等),并且可以有自定义的数值。 C++中的枚举有两种形式:传统的枚举(C-style enum)和C++11引入的强类型枚举(enum class)。传统枚举类似于常量定义,而强类型枚举更...
在Ruby编程语言中,Enumerable模块和Enumerator类是两个非常核心且强大的工具,它们为处理集合数据提供了丰富的功能。本文将深入探讨这两个概念的实现、用途以及如何在实际编程中运用它们。 首先,Enumerable模块是...
"MC Virtual Usb Bus Enumerator驱动程序"是计算机操作系统中用于管理虚拟USB设备的关键组件。它在Windows系统中扮演着重要角色,特别是在模拟USB设备或在虚拟化环境中使用USB设备时。驱动程序是操作系统与硬件之间...
* 枚举器类的实现:`public struct Enumerator : IEnumerator, System.Collections.IEnumerator { ... }` * 使用枚举器类遍历集合:`foreach (T t in list) { ... }` 四、List类的泛型等效类 List类是C#中的一种...
【BusEnum总线枚举驱动器】是一种关键的系统组件,负责在Windows CE、Windows Embedded CE 6.0及其R2版本中初始化和加载设备驱动程序。传统的BusEnum驱动程序在单独的线程中同步加载所有驱动,这可能导致设备启动...
RAR Password Enumerator这是一个破解加密的RAR文件的工具。利用穷举的思想暴力破解加密的RAR文件。 RAR Password Enumerator特点 利用穷举的思想暴力破解加密的RAR文件。 支持带有符号的字串。 支持汉字密码。 ...
在C#中处理USB设备涉及到调用Windows API函数以及使用相关的结构体和枚举类型。这些API函数主要用于获取USB设备的信息、打开设备并读取数据。通过本篇文章的学习,你将能够掌握以下关键技能: - 如何使用Windows API...
在使用 yield 关键字时,.NET 将生成一个 enumerator 对象,该对象将负责生成枚举项。这样可以让开发者使用 foreach 语句来枚举枚举项,而不是强制将所有枚举项生成并返回。 yield 关键字的优点 使用 yield 关键字...
本文将深入探讨ATL中的可持续技术(Persistence)和枚举器(Enumerator)。 首先,我们来看看ATL中的可持续性技术。这是COM组件能够保存和恢复其状态的关键特性。ATL提供了多种接口来实现这一功能,如`...
此外,`IEnumerator<T>` 是泛型版本的迭代器接口,用于处理特定类型的数据。 在C#中实现迭代器模式的步骤通常如下: 1. **定义聚合对象**:创建一个类,实现 `IEnumerable` 或 `IEnumerable<T>` 接口。这些接口...
级枚举 枚举增加数字的键。 如果您枚举相同的键两次,它将枚举为相同的值。 npm install level-enumerate 用法 var enumerator = require ( 'level-enumerate' ) var enumerate = enumerator ( db ) // where db ...