foreach语句
我们可以用foreach语句来遍历数组中的每一个元素。
为什么数组可以这么做,是因为数组提供了叫做 枚举器的对象
获取一个对象的枚举器方法是 调用对象的GetEnumerator方法,那么如果实现了这个方法的类型叫做 可枚举类型
IEnumerator接口
实现IEnumerator接口的枚举器有三个函数成员
Current是返回序列中当前位置项的属性
MoveNext把枚举器前进到下一项的方法
- 新的位置有效 返回true
- 新的位置无效 返回false
- 起始的位置在第一项之前,所有得在第一次使用Current之前调用
Reset是把位置重置为原始状态的方法
所以知道了枚举器,就可以模仿foreach循环遍历集合中的项
IEnumerable接口
可吗,枚举类是实现了IEnumerable接口的类,IEnumerable接口只有一个成员:GetEnumerator方法,它返回对象的枚举器
代码演示如下:
使用IEnumerator和IEnumerable
代码中展示了一个可枚举类:Spectrum,枚举器类为Color_Enumerator
using System; using System.Collections; using System.Linq; namespace ConsoleApp3 { class ColorEnumerator : IEnumerator { private string[] _colors; private int _position = -1; public ColorEnumerator(string[] theColors) { _colors = new string[theColors.Length]; for (int i = 0; i < theColors.Length; i++) { _colors[i] = theColors[i]; } } 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; } return false; } public void Reset() { _position = -1; } } class Spectrum : IEnumerable { private string[] Colors = {"violet", "blue", "cyan", "green", "yellow", "orange", "red"}; public IEnumerator GetEnumerator() { return new ColorEnumerator(Colors); } } class Program { static void Main(string[] args) { Spectrum spectrum = new Spectrum(); foreach (var color in spectrum) { Console.WriteLine(color); } } } }
迭代器
C#提供了更简单的创建枚举器和可枚举类型的方式
//第一个代码
public IEnumerator<string> BlackAndWhite() { yield return "black"; yield return "gray"; yield return "white"; }
//第二个代码 public IEnumerator<string> BlackAndWhite() { string[] theColors = {"black", "gray", "white"}; for (int i = 0; i < theColors.Length; i++) { yield return theColors[i]; } }
迭代器块是有一个或多个yield语句的代码块
它可以是:
方法主体,访问器主体,运算符主体
- yield return语句指定了序列中返回的下一项
- yield break语句指定了在序列中没有其他项
使用迭代器创建枚举器
BlackAndWhite方法是一个迭代器块,可以为MyClass类产生返回枚举器的方法
MyClass还实现了GetEnumerator方法,调用了BlackAndWhite并且返回BlackAndWhite返回的枚举器
class MyClass { public IEnumerator<string> GetEnumerator() { return BlackAndWhite(); } public IEnumerator<string> BlackAndWhite() { yield return "black"; yield return "gray"; yield return "white"; } }
使用迭代器创建可枚举类型
public IEnumerator<string> GetEnumerator() { IEnumerable<string> myEnumerable = BlackAndWhite();//获取可枚举类型 return myEnumerable.GetEnumerator();//获取枚举器 } public IEnumerable<string> BlackAndWhite() { yield return "black"; yield return "gray"; yield return "white"; }