我知道yield关键字指示它出现的方法是迭代器。我只是想知道它如何与List<T>.AddRange
这样的东西一起工作。
让我们使用以下示例:
static void Main()
{
foreach (int i in MyInts())
{
Console.Write(i);
}
}
public static IEnumerable<int> MyInts()
{
for (int i = 0; i < 255; i++)
{
yield return i;
}
}
因此,在上面的示例中,每次生成后,在
foreach
的Main
循环中返回一个值,并将其打印到控制台。如果我们将
Main
更改为此:static void Main()
{
var myList = new List<int>();
myList.AddRange(MyInts());
}
这是如何运作的? yield_code是否为yield语句返回的每个int调用,还是以某种方式等待所有255个值,然后再添加整个范围?
最佳答案
implementation of AddRange
将使用迭代器的IEnumerable
方法迭代.MoveNext()
输入,直到yield
ing方法生成了所有值。可以看到here。
因此,myList.AddRange(MyInts());
被调用一次,其实现迫使MyInts
在继续之前返回其所有值。AddRange
由于实现方式的原因而耗尽了迭代器的所有值,但是以下假设方法将仅评估迭代器的第一个值:
public void AddFirst<T>(IEnumerable<T> collection)
{
Insert(collection.First());
}
在进行此操作时,一个有趣的实验是在
Console.WriteLine(i);
方法中添加MyInts
行,以查看何时生成每个数字。