我编写了一个程序,旨在从给定的起点创建一个随机数字列表。这是一个快速的脏东西,但我在玩它时发现了一个我不太理解的有趣效果。
void Main()
{
List<int> foo = new List<int>(){1,2,3};
IEnumerable<int> bar = GetNumbers(foo);
for (int i = 1; i < 3; i++)
{
foo = new List<int>(){1,2,3};
var wibble = GetNumbers(foo);
bar = bar.Concat(wibble);
}
Iterate(bar);
Iterate(bar);
}
public void Iterate(IEnumerable<int> numbers)
{
Console.WriteLine("iterating");
foreach(int number in numbers)
{
Console.WriteLine(number);
}
}
public IEnumerable<int> GetNumbers(List<int> input)
{
//This function originally did more but this is a cutdown version for testing.
while (input.Count>0)
{
int returnvalue = input[0];
input.Remove(input[0]);
yield return returnvalue;
}
}
运行它的输出是:
iterating
1
2
3
1
2
3
1
2
3
iterating
也就是说我第二次bar
在它为空后立即迭代。
我认为这与我第一次迭代它清空用于生成列表的列表并随后使用这些相同的列表现在为空的列表进行迭代的事实有关。
我的困惑是为什么会这样?为什么我的 IEnumerable 每次枚举时都不会从默认状态开始?有人可以解释一下我到底在做什么吗?
并且要清楚,我知道我可以通过.ToList()
在我的调用中添加一个来解决这个问题,GetNumbers()
这会强制立即评估和存储结果。