yield关键字
yield return 语句返回集合的一个元素,并移动到下一个元素上. yield break可停止迭代.
using System;
using System.Collection;
namespace Wrox.ProCSharp.Arrays
{
public class HelloCollection
{
public IEnumerator GetEnumerator()
{
yield return "Hello";
yield return "World";
}
}
}
包含yield语句的方法或属性也称为迭代块.迭代块必须声明为返回IEnumerator或IEnumerable接口.这个块可以包含多个yield return 语句或yield break语句,但不能包含return 语句
使用迭代块,编译器会生成一个yield类型,其中包含一个状态机,yield类型执行IEnumerator和IDisposable接口的属性和方法.GetEnumerator()方法实例化并返回一个新的yield类型.在yield类型中,变量state定义了迭代的当前位置,每次调用MoveNext()时,当前位置都会改变.MoveNext()封装了迭代块的代码,设置了current变量的值,使Current属性根据位置返回一个对象.如下代码
public class HelloCollection
{
public IEnumerator GetEnumerator()
{
Enumerator enumerator = new Enumerator();
return enumerator;
}
public clss Enumerator : IEnumerator, IDisposable
{
private int state;
private object current;
public Enumerator(int state)
{
this.state = state;
}
bool System.Collections.IEnumerator.MoveNext()
{
switch(state)
{
case 0:
current = "Hello";
state = 1;
return true;
case 1:
current = "World";
state = 2;
return true;
case 2:
break;
}
return false;
}
void System.Collections.IEnumerator.Reset()
{
throw new NotSupportedException();
}
object System.Collections.IEnumerator.Current
{
get
{
return current;
}
}
void IDisposable.Dispose()
{
}
}
}
现在使用yield return 语句,很容易实现允许以不同方式迭代集合的类.类MusicTitles可以用默认方式通过GetEnumerator()方法迭代标题,用Reverse()方法逆序迭代标题,用Subset()方法搜索子集:
public class MusicTitles
{
string[] names = {"aa","bb","cc"};
public IEnumerator GetEnumerator()
{
for(int i = 0; i < 4; i++)
{
yield return names ;
}
}
public IEnumerable Reverse()
{
for(int i = 3; i >= 0; i --)
{
yield return names;
}
}
public IEnumerable Subset(int index, int length)
{
for(int i = index; i < index + length; i++)
{
yield return names;
}
}
}
yield语句还可以完成更复杂的任务,例如从yield return 中返回枚举器.
using System;
using System.Collection;
namespace Wrox.ProCSharp.Arrays
{
public class HelloCollection
{
public IEnumerator GetEnumerator()
{
yield return "Hello";
yield return "World";
}
}
}
包含yield语句的方法或属性也称为迭代块.迭代块必须声明为返回IEnumerator或IEnumerable接口.这个块可以包含多个yield return 语句或yield break语句,但不能包含return 语句
使用迭代块,编译器会生成一个yield类型,其中包含一个状态机,yield类型执行IEnumerator和IDisposable接口的属性和方法.GetEnumerator()方法实例化并返回一个新的yield类型.在yield类型中,变量state定义了迭代的当前位置,每次调用MoveNext()时,当前位置都会改变.MoveNext()封装了迭代块的代码,设置了current变量的值,使Current属性根据位置返回一个对象.如下代码
public class HelloCollection
{
public IEnumerator GetEnumerator()
{
Enumerator enumerator = new Enumerator();
return enumerator;
}
public clss Enumerator : IEnumerator, IDisposable
{
private int state;
private object current;
public Enumerator(int state)
{
this.state = state;
}
bool System.Collections.IEnumerator.MoveNext()
{
switch(state)
{
case 0:
current = "Hello";
state = 1;
return true;
case 1:
current = "World";
state = 2;
return true;
case 2:
break;
}
return false;
}
void System.Collections.IEnumerator.Reset()
{
throw new NotSupportedException();
}
object System.Collections.IEnumerator.Current
{
get
{
return current;
}
}
void IDisposable.Dispose()
{
}
}
}
现在使用yield return 语句,很容易实现允许以不同方式迭代集合的类.类MusicTitles可以用默认方式通过GetEnumerator()方法迭代标题,用Reverse()方法逆序迭代标题,用Subset()方法搜索子集:
public class MusicTitles
{
string[] names = {"aa","bb","cc"};
public IEnumerator GetEnumerator()
{
for(int i = 0; i < 4; i++)
{
yield return names ;
}
}
public IEnumerable Reverse()
{
for(int i = 3; i >= 0; i --)
{
yield return names;
}
}
public IEnumerable Subset(int index, int length)
{
for(int i = index; i < index + length; i++)
{
yield return names;
}
}
}
yield语句还可以完成更复杂的任务,例如从yield return 中返回枚举器.