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

时间:2009-10-27 18:36:41

标签: c# .net foreach

假设我有以下代码:

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

在循环的每次迭代中都会调用someObj.GetMyStrings()吗?改为做以下事情会更好:

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

4 个答案:

答案 0 :(得分:47)

该函数只调用一次,以返回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以使其工作。

答案 1 :(得分:18)

否..函数将被调用一次以获取IEnumerable ..然后将重复调用MoveNext和Current。

答案 2 :(得分:3)

GetMyStrings()返回IEnumerable类型的对象。运行时知道如何处理它。它调用IEnumerable.GetEnumerator()然后在该枚举器对象上调用MoveNext()和Current。

答案 3 :(得分:0)

只是为了解决问题,以防你陷入&#34;所有的问题都是相同的&#34 ;;     for(int x = 0; x&lt; ProvideCeiling(); x ++) 每次 调用该函数。