C# 转换嵌套循环中的收益率

C# 转换嵌套循环中的收益率,c#,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.

我正在学习基础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;
IEnumerable操作系统;
while(p!=null)
{   
foreach(变量x在x中)
os.Add(x);
//....
foreach(变量y在y中)
os.添加(y);
p=GetP();
}
返回操作系统;

这两个代码片段*是“相同”的,只是因为如果执行迭代直到完成,它们将产生相同的对象序列。然而,在迭代过程中发生的事情的实际顺序是非常不同的

  • 如果迭代结果IEnumerable的循环由于中断或异常而提前终止,则返回的代码可能提前停止
  • 添加到集合的代码将在内存中准备新集合。带有yield return的代码使用现有集合生成可以迭代的序列,而无需将结果存储在内存中
  • 具有收益返回的代码可以对迭代过程中迭代内容的更改作出反应。例如,如果在迭代
    X
    的过程中,使用
    yield return
    方法的代码添加到集合
    Y
    ,则在迭代
    Y
    时将返回新项目。第二个代码示例将无法执行相同的操作
*让我们假设
IEnumerable
有一个
Add
方法;实际上,您可能最终会使用一个
列表
或其他集合。

这两个代码片段*是“相同”的,只是因为如果执行迭代直至完成,它们将生成相同的对象序列。然而,在迭代过程中发生的事情的实际顺序是非常不同的

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

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

我相信你在收益率工作的一般方式上是正确的。Yield应该比仅仅添加到集合中更具性能,因为它只有在需要时才可以访问

发件人:

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


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

我相信您在收益率工作的一般方式上是正确的。Yield应该比仅仅添加到集合中更具性能,因为它只有在需要时才可以访问

发件人:

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


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

从技术上讲,不可以,因为您无法直接创建
IEnumerable
,第二个示例将无法工作。无论哪种方式,第一个示例都会按顺序返回项,
X
首先,然后
Y
,然后调用
GetP
,而第二个示例将它们全部添加到枚举器并调用
GetP
。第一个示例可能会改变
GetP
返回的方式,并可能给出不同的结果。
IEnumerable
没有
add
方法,因此您无法通过引用
os
向其添加。从技术上讲,不可以,因为您无法直接创建
IEnumerable
。无论哪种方式,第一个示例都会按顺序返回项,
X
首先,然后
Y
,然后调用
GetP
,而第二个示例将它们全部添加到枚举器并调用
GetP
。第一种方法可能会改变
GetP
返回的方式,并可能给出不同的结果。
IEnumerable
没有
add
方法,因此无法通过引用
os
向其添加。