在嵌套循环中转换yield yield

时间:2015-05-29 12:47:26

标签: c#

我正在学习基本的C# 我有以下代码段

while(p!=null)
{
   foreach(var x in X)
      yield return x;
   //....
   foreach(var y in Y)
      yield return y;
   p=GetP();
}

代码是否与

相同
IEnumerable<object> os;
while (p!=null)
{   
   foreach(var x in X)
      os.Add(x);
   //....
   foreach(var y in Y)
      os.Add(y);
   p=GetP();
}
return os;

???

2 个答案:

答案 0 :(得分:4)

两个代码片段 * 仅在某种意义上“相同”,如果迭代执行完成,它们将产生相同的对象序列。但是,在迭代过程中发生的实际序列是非常不同的。

  • 如果由于yield return或异常导致迭代结果IEnumerable的循环提前终止,则break代码可能会提前停止。
  • 添加到集合的代码会在内存中准备新的集合。具有yield return的代码使用现有集合来生成可以迭代的序列,而不将结果存储在内存中。
  • 带有yield return的代码可以对迭代过程中迭代的变化作出反应。例如,如果使用yield return方法的代码在迭代Y的过程中添加到集合X,则在迭代Y时将返回新项目。第二个代码示例将无法执行相同的操作。

* 让我们假装IEnumerable<T>有一个Add方法;实际上,你最终可能会使用List<T>或其他一些集合。

答案 1 :(得分:0)

我相信你对收益率的一般方式是正确的。产量应该比仅添加到集合中更多的格式,因为它只在需要时才能访问。

来自MSDN

使用yield return语句一次返回一个元素。

使用foreach语句或LINQ查询来使用迭代器方法。 foreach循环的每次迭代都会调用迭代器方法。在迭代器方法中达到yield return语句时,将返回表达式,并保留代码中的当前位置。下次调用迭代器函数时,将从该位置重新开始执行。