假设我有以下代码:
foreach(string str in someObj.GetMyStrings())
{
// do some stuff
}
在循环的每次迭代中都会调用someObj.GetMyStrings()
吗?改为做以下事情会更好:
List<string> myStrings = someObj.GetMyStrings();
foreach(string str in myStrings)
{
// do some stuff
}
答案 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 ++) 每次 调用该函数。