迭代器(yield return )

yield return语句返回集合的一个元素,并移动到下一个元素上。yield break可停止迭代。包含yield语句的方法或属性也称为迭代块。迭代块必须声明为返回IEnumerator或IEnumerable接口。这个块可以包含多个yield return语句或yield break语句,但不能包含return语句。

下面是事例

代码
view plaincopy to clipboardprint?
using System;
using System.Collections.Generic;
using System.Text;
using System.Collections.Specialized;
using System.Collections;
using System.Diagnostics;
namespace ConsoleTest
{
public class ConsoleTest
{
public static void Main(string[] args)
{
// Test 1.
// yield break.
// yield return.

#region Test 1
ListClass list
= new ListClass();
foreach (string i in list)
{
Console.Write(i);
}
#endregion

// Test 2 yield Iterator.
#region Test 2
Node
<string>[] nodes = new Node<string>[8];
nodes[
0] = new Node<string>("A");
nodes[
1] = new Node<string>("B");
nodes[
2] = new Node<string>("C");
nodes[
3] = new Node<string>("D");
nodes[
4] = new Node<string>("E");
nodes[
5] = new Node<string>("F");
nodes[
6] = new Node<string>("G");
nodes[
7] = new Node<string>("H");
nodes[
0].LeftNode = nodes[1];
nodes[
0].RightNode = nodes[2];
nodes[
1].RightNode = nodes[3];
nodes[
2].LeftNode = nodes[4];
nodes[
2].RightNode = nodes[5];
nodes[
3].LeftNode = nodes[6];
nodes[
3].RightNode = nodes[7];
BinaryTree
<string> tree = new BinaryTree<string>(nodes[0]);
BinaryTreeScanInOrder
<string> inOrder = new BinaryTreeScanInOrder<string>(tree);
foreach (string item in inOrder.InOrder)
{
Console.WriteLine(item);
}
Console.ReadLine();
#endregion
}
}
#region For Test 1
public class ListClass : IEnumerable
{
public IEnumerator GetEnumerator()
{
yield return "With an iterator, ";
yield return "more than one ";
yield break;
yield return "value can be returned";
yield return ".";
}
}
#endregion
#region For Test 2
public class Node<T>
{
public Node<T> LeftNode;
public Node<T> RightNode;
public T Item;
public Node(T item)
{
this.Item = item;
}
}
public class BinaryTree<T>
{
public Node<T> Root;
public BinaryTree(Node<T> root)
{
this.Root = root;
}
}
public class BinaryTreeScanInOrder<T>
{
private BinaryTree<T> _binaryTree;
public BinaryTreeScanInOrder(BinaryTree<T> binaryTree)
{
this._binaryTree = binaryTree;
}
public IEnumerable<T> InOrder
{
get
{
return ScanInOrder(_binaryTree.Root);
}
}
public IEnumerable<T> ScanInOrder(Node<T> root)
{
if (root.LeftNode != null)
{
foreach (T item in ScanInOrder(root.LeftNode))
{
yield return item;
}
}
yield return root.Item;
if (root.RightNode != null)
{
foreach (T item in ScanInOrder(root.RightNode))
{
yield return item;
}
}
}
}
#endregion
}

 

一个迭代器块(iterator block)是一个能够产生有序的值序列的块。迭代器块和普通语句块的区别就是其中出现的一个或多个yield语句。

yield return语句产生迭代的下一个值。
yield break语句表示迭代完成。
只要相应的函数成员的返回值类型是一个枚举器接口(见下)或是一个可枚举接口(见下),一个迭代器块就可以用作方法体、运算符体或访问器体。

迭代器块并不是C#语法中的独立元素。它们受多种因素的制约,并且对函数成员声明的语义有很大影响,但在语法上它们只是块(block)。

当一个函数成员用一个迭代器块来实现时,如果函数成员的形式参数列表指定了ref或out参数,则会引起编译错误。

如果在迭代器块中出现了return语句,则会因此编译错误(但yield return语句是允许的)。

如果迭代器块包含不安全上下文,则会引起编译错误。一个迭代器块必须定义在一个安全的上下文中,即使它的声明嵌套在一个不安全上下文中。

 枚举器接口
枚举器(enumerator)接口包括非泛型接口System.Collections.IEnumerator和泛型接口System.Collections.Generic.IEnumerator<T>的所有实例化。在这一章中,这些接口将分别称作IEnumerator和IEnumerator<T>。

 可枚举接口
可枚举(enumerable)接口包括非泛型接口System.Collections.IEnumerable和泛型接口System.Collections.Generic.IEnumerable<T>。在这一章中,这些接口分别称作IEnumerable和IEnumerable<T>。

生成类型

一个迭代器块能够产生一个有序的值序列,其中所有的制具有相同的类型。这个类型称为迭代器块的生成类型(yield type)。


本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/liaolian9948/archive/2010/06/01/5639090.aspx

posted @ 2010-06-03 17:15  驢騎士  阅读(351)  评论(0编辑  收藏  举报