在编写可枚举的时候,yield return var是什么?

时间:2011-07-18 19:32:21

标签: c#

  

可能重复:
  What is the yield keyword used for in C#?

假设我的代码如下:

(steam是文件流)

using(BinaryWriter bw = new BinaryWriter(stream))
{
  foreach(byte[] b in BreakBytes(objectOfBytes))
  {
    writer.Write(b);
  }
}

因此,要使BreakBytes工作,它必须执行以下操作:

public static IEnumerable<byte[]> BreakBytes(byte[] b)
{
  ..
  while(..) {

     yield return some_buffer;

  }
  ..
}

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

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

4 个答案:

答案 0 :(得分:3)

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

答案 1 :(得分:1)

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

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

这个有点奇怪的结构带来的好处是,如果只枚举IEnumerable的一部分,则只需要生成该部分。

答案 2 :(得分:0)

Jon Skeet可以告诉你关于他们的一切:http://csharpindepth.com/Articles/Chapter6/IteratorBlockImplementation.aspx

是。它跟踪其内部状态。

答案 3 :(得分:0)

yield return语句是迭代器使用实现IEnumerable和IEnumerator接口的集合的GetEnumerator()和MoveNext()方法向调用者返回一个几乎总是foreach循环隐含的答案的点。 / p>

它确实保持了它的状态。像这样的迭代器块里面的代码可以被认为在yield return语句之后暂时停止,直到下次调用MoveNext()方法时它会向右移回它停止的位置,直到它达到另一个yield return。 / p>

对于更深入的解释,我强烈推荐这本书C# in Depth, Second Edition