如何通过函数循环的结果什么时候的foreach的工作?什么时候、函数、结果、工作

2023-09-02 10:28:29 作者:- 少年多少年。

假设我有以下的code:

Suppose I have the following code:

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

威尔 someObj.GetMyStrings()算得上是循环的每次迭代?它会更好做以下代替:

Will someObj.GetMyStrings() be called on every iteration of the loop? Would it be better to do the following instead:

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

推荐答案

函数的只有调用一次,返回一个的IEnumerator&LT; T&GT; ;在这之后,的MoveNext()方法和当前属性用于遍历结果:

The function's only called once, to return an IEnumerator<T>; after that, the MoveNext() method and the Current property are used to iterate through the results:

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

在某种程度上等同于:

is somewhat equivalent to:

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

请注意迭代器布置在结束 - 这是从迭代器块,例如资源配置特别重要:

Note that the iterator is disposed at the end - this is particularly important for disposing resources from iterator blocks, e.g.:

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

在上面的code,你真的要当你完成迭代文件被关闭,则编译器工具的IDisposable 巧妙,使这项工作。

In the above code, you really want the file to be closed when you finish iterating, and the compiler implements IDisposable cunningly to make that work.