列出<T> .AddRange和yield语句

Fla*_*ack 7 .net c# foreach list

我知道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;
    }
}
Run Code Online (Sandbox Code Playgroud)

因此,在每个yield之后的上述示例中,在foreach循环中返回一个值Main并将其打印到控制台.

如果我们改为Main:

static void Main()
{
    var myList = new List<int>();
    myList.AddRange(MyInts());
}
Run Code Online (Sandbox Code Playgroud)

这是如何运作的?是否AddRange为yield语句返回的每个int调用,还是在添加整个范围之前以某种方式等待所有255个值?

dee*_*see 5

实现AddRangeIEnumerable使用迭代器的.MoveNext()方法迭代输入,直到您的yielding 方法生成了所有值。这可以在这里看到。

SomyList.AddRange(MyInts());被调用一次,它的实现强制MyInts在继续之前返回所有它的值。

AddRange 由于实现的方式而耗尽了迭代器的所有值,但以下假设方法只会评估迭代器的第一个值:

public void AddFirst<T>(IEnumerable<T> collection)
{
    Insert(collection.First());
}
Run Code Online (Sandbox Code Playgroud)

一个有趣的实验是Console.WriteLine(i);在您的MyInts方法中添加一行以查看每个数字何时生成。