我正在尝试理解以下代码的行为原因:
在主函数中,我获得了一个名为x的新“生成器”(请原谅我使用python术语),然后尝试两次枚举它。 第一次,我取前三个元素并将它们打印出来:我期望程序先打印“Hello world!”,然后打印从0到2的数字。 第二次,我取相同的可枚举对象并跳过3个元素。 我期望程序打印从6到9的数字,而不是首先打印“Hello world!”。
但是,第二次程序会再次打印“Hello world!”,然后从3开始枚举,一直到9。
我不明白:为什么Foo()被调用了两次?
编辑1:不是重复问题。链接的“重复”问题询问编写可枚举对象时的最佳实践,而我在这里遇到了消耗其值的问题。
编辑2:我接受了一个答案,它并不好,但包含了一个让我理解问题的参考链接。 对我来说令人困惑的是foreach循环在枚举IEnumerable时的实际工作方式,因此我将在此解释它以供参考。
IEnumerable是值序列-底层实现无关紧要,只要它是可以按顺序给你值的东西即可。 当您在其中使用foreach循环时,它会创建一个Enumerator对象,这是一个光标,用于跟踪循环到达的位置。
因此,第一次循环创建了第一个枚举器,该枚举器必须启动我的生成器方法并打印第一个字符串。
第二个循环无法拾取上一个枚举器(正如我所认为的那样)。 相反,它实例化了第二个枚举器,该枚举器又重新启动了生成器,从而打印了第二个字符串。
对于任何阅读此内容的Pythonista,请注意,它与Python中生成器的工作方式完全相反(在其中重用可迭代对象不会重新启动它)。
我正在尝试理解以下代码的行为原因:
using System;
using System.Collections.Generic;
using System.Linq;
namespace ConsoleApplication
{
internal class Program
{
private static IEnumerable<int> Foo()
{
Console.WriteLine("Hello world!");
for (var i = 0; i < 10; i++)
yield return i;
}
public static void Main(string[] args)
{
var x = Foo();
var y = x.Take(3);
foreach (var i in y)
Console.WriteLine(i);
var z = x.Skip(3);
foreach (var i in z)
Console.WriteLine(i);
}
}
}
在主函数中,我获得了一个名为x的新“生成器”(请原谅我使用python术语),然后尝试两次枚举它。 第一次,我取前三个元素并将它们打印出来:我期望程序先打印“Hello world!”,然后打印从0到2的数字。 第二次,我取相同的可枚举对象并跳过3个元素。 我期望程序打印从6到9的数字,而不是首先打印“Hello world!”。
但是,第二次程序会再次打印“Hello world!”,然后从3开始枚举,一直到9。
我不明白:为什么Foo()被调用了两次?
编辑1:不是重复问题。链接的“重复”问题询问编写可枚举对象时的最佳实践,而我在这里遇到了消耗其值的问题。
编辑2:我接受了一个答案,它并不好,但包含了一个让我理解问题的参考链接。 对我来说令人困惑的是foreach循环在枚举IEnumerable时的实际工作方式,因此我将在此解释它以供参考。
IEnumerable是值序列-底层实现无关紧要,只要它是可以按顺序给你值的东西即可。 当您在其中使用foreach循环时,它会创建一个Enumerator对象,这是一个光标,用于跟踪循环到达的位置。
因此,第一次循环创建了第一个枚举器,该枚举器必须启动我的生成器方法并打印第一个字符串。
第二个循环无法拾取上一个枚举器(正如我所认为的那样)。 相反,它实例化了第二个枚举器,该枚举器又重新启动了生成器,从而打印了第二个字符串。
对于任何阅读此内容的Pythonista,请注意,它与Python中生成器的工作方式完全相反(在其中重用可迭代对象不会重新启动它)。