【问题标题】:When writing an enumerable, what does yield return var? [duplicate]编写可枚举时,yield return var 是什么? [复制]
【发布时间】:2011-10-07 23:25:52
【问题描述】:

可能重复:
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;

  }
  ..
}

yield 到底在做什么?它会跟踪它的位置吗?

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

【问题讨论】:

    标签: c#


    【解决方案1】:

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

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

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

    【讨论】:

      【解决方案2】:

      简而言之,该方法中的代码被重写为一个状态机,它会按照您的猜测执行:它跟踪它在循环中的位置,返回给调用者,然后从中断的地方继续。

      【讨论】:

        【解决方案3】:

        Jon Skeet 可以告诉你所有关于它们的信息:http://csharpindepth.com/Articles/Chapter6/IteratorBlockImplementation.aspx

        是的。它跟踪其内部状态。

        【讨论】:

          【解决方案4】:

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

          它确实保持了它的状态。可以认为像这样的迭代器块内的代码在 yield return 语句之后会暂时停止,直到下次调用 MoveNext() 方法时,它会从中断的地方恢复,直到遇到另一个 yield return。

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

          【讨论】:

            猜你喜欢
            • 2017-07-29
            • 1970-01-01
            • 2018-05-18
            • 2019-11-28
            • 2023-04-01
            • 2012-07-08
            • 2013-07-27
            • 1970-01-01
            • 2016-09-27
            相关资源
            最近更新 更多