关于C#:在编写可枚举的时候,yield return var是什么?


When writing an enumerable, what does yield return var?

本问题已经有最佳答案,请猛点这里访问。

Possible Duplicate:
What is the yield keyword used for in C#?

假设我有如下代码:

(蒸汽是一股蒸汽流)

1
2
3
4
5
6
7
using(BinaryWriter bw = new BinaryWriter(stream))
{
  foreach(byte[] b in BreakBytes(objectOfBytes))
  {
    writer.Write(b);
  }
}

因此,要使breakbytes工作,它必须执行如下操作:

1
2
3
4
5
6
7
8
9
10
public static IEnumerable<byte[]> BreakBytes(byte[] b)
{
  ..
  while(..) {

     yield return some_buffer;

  }
  ..
}

收益率究竟在做什么?它是否跟踪位置?

我相信它会返回到调用foreach循环,但当再次调用时会继续到下一个迭代?


简言之,方法中的代码被重新编写为一个状态机,它可以像您怀疑的那样工作:跟踪它在循环中的位置,返回到调用方,并在它停止的地方继续。


yield在C语言中非常特殊,因为它不遵循正常的控制流程。

迭代返回的IEnumerable时,将调用并运行BreakBytes函数,直到生成值为止。然后控制权将传回foreach循环。当循环进入下一个项目时,BreakBytes将恢复并运行,直到它碰到另一个yield

这个有点奇怪的结构提供了这样的好处:如果只枚举IEnumerable的一部分,那么只需要生成该部分。


yield return语句是迭代器向调用方返回答案的点,调用方几乎总是使用实现IEnumerable和IEnumerator接口的集合的getEnumerator()和moveNext()方法来实现foreach循环隐式。

它确实保持了它的状态。类似这样的迭代器块内部的代码可以被认为是在yield return语句之后暂时停止的,直到下次调用moveNext()方法时,它将从停止的地方恢复到另一个yield返回。

对于更深入的解释,我强烈推荐第二版《深度C》一书。


乔恩·斯基特可以告诉你所有关于它们的信息:http://csharpindepth.com/articles/chapter6/iteratorblockimplementation.aspx

对。它跟踪其内部状态。