一尘不染

遍历函数结果时,foreach如何工作?

c#

假设我有以下代码:

foreach(string str in someObj.GetMyStrings())
{
    // do some stuff
}

someObj.GetMyStrings()在循环的每次迭代中被调用吗?最好改为执行以下操作:

List<string> myStrings = someObj.GetMyStrings();
foreach(string str in myStrings)
{
    // do some stuff
}


阅读 281

收藏
2020-05-19

共1个答案

一尘不染

该函数仅调用一次,以返回IEnumerator<T>; 之后,使用MoveNext()方法和Current属性来迭代结果:

foreach (Foo f in GetFoos())
{
    // Do stuff
}

在某种程度上等效于:

using (IEnumerator<Foo> iterator = GetFoos().GetEnumerator())
{
    while (iterator.MoveNext())
    {
        Foo f = iterator.Current;
        // Do stuff
    }
}

请注意,迭代器放置在末尾-这对于从迭代器块释放资源特别重要,例如:

public IEnumerable<string> GetLines(string file)
{
    using (TextReader reader = File.OpenText(file))
    {
        string line;
        while ((line = reader.ReadLine()) != null)
        {
            yield return line;
        }
    }
}

在上面的代码中,您确实希望在完成迭代后关闭文件,并且编译器IDisposable巧妙地实现了该工作。

2020-05-19