位置:首页 > 软件操作教程 > 编程开发 > C# > 问题详情

C# 迭代器

提问人:刘团圆发布时间:2020-12-07

    Enumerable接口允许使用foreach循环。在foreach循环中并不是只能使用集合类,相反,在foreach循环中使用定制类通常有很多优点。

    但是,重写使用foreach循环的方式或者提供定制的实现方式并不一定很简单。为了说明这一点,下面有必要深入研究一下foreach循环。在foreach循环中,迭代一个collectionObject集合的过程如下:

(1)调用 collectionObjectGetEnumeratorO,返回一个Enumerator引用。这个方法可通过IEnumerable接口的实现代码来获得,但这是可选的。

(2)调用所返回的IEnumerator接口的MoveNextQ方法。

(3)如果MoveNextO方法返回true,就使用IEnumerator接口的Current属性来获取对象的一个引用,用于 foreach 循环。

(4)重复前面两步,直到MoveNextO方法返回felse为止,此时循环停止。

    所以,为在类中进行这些操作,必须重写几个方法,跟踪索引,维护Qirrent属性,以及执行其他一些操作。这要做许多工作。

    —个较简单的替代方法是使用迭代器。使用迭代器将有效地自动生成许多代码,正确地完成所有任务。而且,使用迭代器的语法掌握起来非常容易。

    迭代器的定义是,它是一个代码块,按顺序提供了要在foreach块中使用的所有值。一般情况下,这个代码块是一个方法,但也可以使用属性访问器和其他代码块作为迭代器。这里为简单起见,仅介绍方法。

    无论代码块是什么,其返回类型都是有限制的。与期望正好相反,这个返回类型与所枚举的对象类型不同。例如,在表示Animal对象集合的类中,迭代器块的返回类型不可能是Animal。两种可能的返回类型是前面提到的接口类型:IEnumerable和IEnumerator。使用这两种类型的场合是:

    •如果要迭代一个类,则使用方法GetEnumerator(),其返回类型是IEnumerator。

    •如果要迭代一个类成员,例如一个方法,则使用IEnumerable。

在迭代器块中,使用yield关键字选择要在foreach循环中使用的值。其语法如下:

    yield return <value>;

利用这个信息就足以建立一个非常简单的示例,如下所示(该示例包含在代码文件SimpleIterators\Program.cs中):

public static IEnumerable SimpleList()

{

    yield return "string 1"; 

    yield return "string 2"; 

    yield return "string 3";

}

static void Main(string[] args)

{

    foreach (string item in SimpleList())

        WriteLine (item);

    ReadKey();

}

    在此,静态方法SimpleListO就是迭代器块。它是一个方法,所以使用IEnumerable返回类型。SimpleList()使用yieid关键字为使用它的foreach块提供了 3个值,每个值都输出到屏幕上,结果如图所示。

image.png

    显然,这个迭代器并不是特别有用,但它确实能够演示迭代器的机制,说明实现迭代器有多么简单。看看代码,读者可能会疑惑代码是如何知道返回string类型的项。实际上,并没有返回string类型的项,而是返回object类型的值。因为object是所有类型的基类,所以可从yield语句中返回任意类型。

    但编译器的智能程度很高,所以我们可以把返回值解释为foreach循环需要的任何类型。这里代码需要string类型的值,而这正是我们要使用的值。如果修改一行yield代码,让它返回一个整数,就会在foreach循环中出现一个类型转换异常。


对于迭代器,还有一点要注意。可以使用下面的语句中断将信息返回给foreach循环的过程:

    yield break;

在遇到迭代器中的这个语句时,迭代器的处理会立即中断,使用该迭代器的foreach循环也一样。


继续查找其他问题的答案?

相关视频回答
回复(0)
返回顶部