迭代器被用来遍历聚合结构(相当于数据集合),是一种方法、get 访问器或运算符,它通过使用 yield 关键字对聚合结构执行自定义迭代。Yield 是一组循环语句用以返回当前值和跳转下一次循环。
一般通过使用foreach 语句调用迭代器,而 foreach 要求遍历的结构是枚举器或可枚举类型,从而需要实现枚举器接口(IEnumerator)或可枚举接口(IEnumerable)。接口中包含 foreach 必须的 GetEnumerator、MoveNet、Reset 和 Current 成员,但在编程时一般只需实现GetEnumerator 成员,按照官方的说法是当编译器检测到迭代器时,它将自动生成Current、MoveNext 和Current 方法。
以下分别介绍4种实现迭代器的方法。
1 foreach 迭代
示例取自 msdn,是使用 foreach 遍历字符串数组。
using System;
public class SplitTest
{
public static void Main()
{
string words = "This is a list of words, with: a bit of punctuation" +
"\tand a tab character.";
string[] split = words.Split(new Char[] { ' ', ',', '.', ':', '\t' });
foreach (string s in split)
{
if (s.Trim() != "")
Console.WriteLine(s);
}
}
}
字符串数组自身实现了上述接口,因而可以直接使用 foreach 语句遍历,如果在自定义类型中,使用该种方法,则需全部实现 GetEnumerator、MoveNet、Reset 和 Current 成员。
2 匿名迭代器
在使用匿名迭代器时,只需要实现 GetEnumerator成员,实力取自《c# 自学手册》,其使用了 yield 返回迭代值。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace 匿名迭代
{
class MyIterator
{
private static int Max = 10;
public IEnumerator<int> GetEnumerator()
{
for (int i = 0; i < Max; i++)
{
yield return i;
}
}
}
class Program
{
static void Main(string[] args)
{
//创建对面
MyIterator iterator = new MyIterator();
foreach (int i in iterator)
{
Console.Write(i + " ");
}
Console.WriteLine();
}
}
}
3 命名迭代器
命名迭代器是以满足特定需要,对应创建的迭代器。相应的其可以有参数列表(签名),用以控制迭代的步长或次数等。下面是一个于特定开始和结束的命名迭代器。using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
namespace 命名迭代器
{
class MyIterator
{
public IEnumerable MyEnumerator(int s, int e)
{
for (int i = s; i < e; i++)
{
yield return i;
}
}
}
class Program
{
static void Main(string[] args)
{
//创建对面
MyIterator iterator = new MyIterator();
foreach (int i in iterator.MyEnumerator(1, 9))
{
Console.Write(i + " ");
}
Console.WriteLine();
}
}
}
4 get 访问迭代器
下面使用get 访问迭代器输出“nihao!”,其中由 yield return 返回值,yield break 终止迭代。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
namespace get_iterator
{
class MyIterator
{
public IEnumerable MyEnAttribute
{
get
{
yield return "ni";
yield return "hao!";
yield break;
}
}
}
class Program
{
static void Main(string[] args)
{
//
MyIterator iterator = new MyIterator();
foreach (string s in iterator.MyEnAttribute)
{
Console.Write(s + " ");
}
Console.WriteLine();
}
}
}
综上所述,迭代器有以下优点,对聚合结构的遍历,但不需显示结构的内部构成;使用迭代器从而使得遍历与结构分离,符合面向对面的思想;上述方法几何对所有有需要的聚合结构都能使用,且非常方便,由此其实用性非常强。
5 参考
迭代器(C# 编程指南)