How Yield works within a ForEach block?
在下面所示的
1 2 3 4 | foreach (int i in lstNumbers) { yield return i; } |
它是在接收到值时开始返回,还是在末尾返回最终列表?
它与以下有什么不同:
1 2 3 4 | foreach (int i in lstNumbers) { return i; } |
在本例中,它将逐个返回所有值,但使用代码需要开始对结果集进行迭代:
1 2 3 4 | foreach (int i in lstNumbers) { yield return i; } |
请看下面的示例,该示例将在控制台上打印
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | using System; using System.Collections.Generic; using System.Linq; class Program { static void Main() { foreach (var item in Get().Take(2)) { Console.WriteLine(item); } } static IEnumerable<int> Get() { foreach (var item in new[] { 1, 2, 3 }) { yield return item; } } } |
在这种情况下,您可能不需要做出任何让步,只需返回结果,因为您已经拥有了它:
1 | return lstNumbers; |
在第二种情况下:
1 2 3 4 | foreach (int i in lstNumbers) { return i; } |
您只需返回列表的第一个值,迭代就会立即中断。
在第一种情况下,它只是在调用
调用方再次对函数调用迭代器之后,它将跳转到下一个迭代。
举例说明:
1 2 3 4 5 6 | int GetNextNumber() { foreach (int in in lstNumbers) { yield return in; //returns on first hit } } |
之后
1 2 3 4 5 | foreach(var i in GetNextNumber()) { //process number got from the GetNextNumber() //on next iteration GetNextNumber() will be called again // so the next number from lstNumbers will be returned } |
这是处理长数据流的一种非常常见的方法,在这种方法中,您依次选择IT流程中的一部分,然后请求另一个流程,等等。
在第二种情况下,相反,您将始终返回列表中的第一个元素,并且永远不会跳转到其他元素。