C#4.0图解教程 - 第20章 枚举数和迭代器
20.1 枚举数和可枚举类型
在.NET中获取一个对象枚举数的标准方法是调用对象的 GetEnumerator 方法。实现 GetEnumerator 方法的类型叫做可枚举类型(enumerable type或enumerable)。数组是可枚举类型。
20.2 使用 IEnumerator 接口
IEnumerator: 接口包含3个函数成员:Current、MoveNext、Reset。
Current: 返回序列中当前位置项的属性。
注意:它是只读属性。返回 object 类型引用,可返回任何类型。
MoveNext: 是把枚举位置前进到集合中的下一项的方法。返回布尔值,指示新的位置是有效位置或已经超过了序列的尾部。
注意:位置有效返回 ture。无效返回 false。枚举数的原始位置在序列中第一项之前。MoveNext 不许在第一次实用 Current 之前使用。
Reset: 方法把位置重置为原始状态。
-
class Program
-
{
-
static void Main(string[] args)
-
{
-
int[] arr ={10, 12, 11,3};
-
//foreach
-
foreach (var i in arr)
-
{
-
Console.WriteLine(i);
-
}
-
-
//利用IEnumerator模仿foreach
-
IEnumerator Myarr = arr.GetEnumerator();
-
while (Myarr.MoveNext())
-
{
-
int ie = (int)Myarr.Current;
-
Console.WriteLine(ie);
-
}
-
}
-
}
20.3 IEnumerable 接口
IEnumerable接口只有一个成员——GetEnumerator方法,它返回对象的枚举数。
下图中ColorEnumerator实现了IEnumerator接口。
实用IEnumerable与IEnumerator的示例
旁白:看作20.6 IEnumerator<T> 接口的示例
-
using System;
-
using System.Collections;
-
using System.Collections.Generic;
-
-
namespace Examples
-
{
-
class ColorEnumerator : IEnumerator<string>
-
{
-
string[] Colors;
-
int Position = -1;
-
-
public string Current // Current--generic
-
{
-
get { return Colors[Position]; }
-
}
-
-
object IEnumerator.Current // Current--non-generic
-
{
-
get { return Colors[Position]; }
-
}
-
-
public bool MoveNext() // MoveNext
-
{
-
if (Position < Colors.Length - 1)
-
{
-
Position++;
-
return true;
-
}
-
else
-
return false;
-
}
-
-
public void Reset() // Reset
-
{
-
Position = -1;
-
}
-
-
public void Dispose() { }
-
-
public ColorEnumerator(string[] colors) // Constructor
-
{
-
Colors = new string[colors.Length];
-
-
for (int i = 0; i < colors.Length; i++)
-
Colors[i] = colors[i];
-
}
-
}
-
-
class MyColors : IEnumerable
-
{
-
string[] Colors = { "Red", "Yellow", "Blue" };
-
-
public IEnumerator GetEnumerator()
-
{
-
return new ColorEnumerator(Colors);
-
}
-
}
-
-
class Program
-
{
-
static void Main()
-
{
-
MyColors mc = new MyColors();
-
foreach (string color in mc)
-
Console.WriteLine(color);
-
Console.WriteLine("==============");
-
IEnumerator ie = mc.GetEnumerator();
-
while (ie.MoveNext())
-
{
-
string i = (string)ie.Current;
-
Console.WriteLine(i);
-
}
-
Console.WriteLine("==============");
-
-
}
-
}
-
}
-
20.6 IEnumerator<T> 接口
IEnumeranble<T> 接口从另外两个接口继承——非泛型 IEnumerator 接口和 IDisposable 接口。它肯定实现了它们的成员。
IDisposable接口只有一个叫Dispose的类型为void的无参方法,用于释放类占据的非托管资源。
IEnumerator<T>和IEnumerator都有一个叫做Current的成员,我们应该显示实现IEnumerator版本。
20.7 IEnumerable<T> 接口
由于类必须实现两个GetEnumerator方法,我们需要显示实现非泛型版本,并在类中实现泛型版本。
20.8 迭代器
下面迭代器返回一个泛型枚举数,该枚举数返回3个string类型的项。
yield renturn 语句声明知识枚举的下一项。
下面是方法另一个版本,输出同样的结果
yield 关键字向编译器指示它所在的方法是迭代器块。
yield 语句只能出现在 iterator(迭代器) 块中,这种块可作为方法、运算符或访问器的主体实现
20.9 常见迭代器模式