yield return 在 c# 中如何工作

问题描述 投票:0回答:1

我有以下代码。

public static void main(string []args)
{

  var intergers = GetCollection();

  foreach(var val in intergers)
  {
   console.writeline(val);
   }

}

public IEnumerable<int> GetCollection()
{

  yield return 10;

  var obj = new MyClass();
  obj.performLargeAction();

  yield return 1;

  var obj = new MyClass();
  obj.perform();

  yield return 2;

  console.writeline("I am finished now");  
}

现在,当我调试代码并看到 foreach 迭代时,我看到第一次方法执行直到yield return 10,然后控制返回到 foreach 循环,在yield return 10之后的下一个迭代代码中直到执行yield return 1在下一次迭代中,它从yield return 1之后的行开始执行,直到yield return,在下一次迭代中它 调用 console.writeline();

因此,通过这种行为,我很想知道 .net 是否暂停返回 IEnumerable 的方法的执行并将其位置计数器或状态保存到堆栈中,下一次迭代再次弹出该位置并将其设置为程序计数器或位置柜台和所有这些东西或

我读过一些内容,yield 是一个 c# 功能,因此上面的代码被转换为 IL,并且yield 部分被一个名为 YieldEnumerator 的类替换,该类存储状态、当前和其他内容。但我仍然无法理解它的实际功能。所以,我想知道它的内部工作形式从开始到结束。

c# .net ienumerable observablecollection ienumerator
1个回答
0
投票

收益回报

  • 基本上仅适用于 IEnumerator / IEnumerator
  • 目的是从 IEnumerable / Collection 中一次获取一项

例如

我们有这样的收藏

cities =  {
    "bangalore",
    "hyderabld",
    "cochin",
    "chennai"
}

有需要,按键时我需要给出城市名称,

这不能通过正确的 return 语句来完成,因为

string GetCityName(){
    for (int i=0; i<cities.count(); i++){
        return cities[i];
    }
    return "";
}

现在 i 的值必须在每次调用时保持递增,并且应该记住下一次调用以获取下一项,但上面的代码将始终返回第一个值,因为 i 将重新初始化为 0。 现在这就是 IEnumerator 与 IEnumerable 结合所做的事情。

所以我可以重写 GetCityName 并返回如下所示的结果

IEnumerable<string> GetCityName(){
    for (int i=0; i<cities.count(); i++){
        yield return cities[i];
    }
}

现在,对于上述每个调用,都会依次返回城市名称

这个魔法是由 IEnumerable.GetEnumerator() 处理的,它返回一个枚举器; 然后 IEnumerator.MoveNext() 将增加指针并记住它。 IEnumerator.Current 将返回集合[指针]; 来自微软文档的收益:https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/statements/yield

© www.soinside.com 2019 - 2024. All rights reserved.