我知道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;
    }
}

因此,在上面的示例中,每次生成后,在foreachMain循环中返回一个值,并将其打印到控制台。

如果我们将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行,以查看何时生成每个数字。

10-08 03:58