题
假设我有以下代码:
foreach(string str in someObj.GetMyStrings())
{
// do some stuff
}
在循环的每次迭代中都会调用someObj.GetMyStrings()
吗?改为做以下事情会更好:
List<string> myStrings = someObj.GetMyStrings();
foreach(string str in myStrings)
{
// do some stuff
}
解决方案
该函数只调用一次,返回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
以使其工作。
其他提示
否..函数将被调用一次以获取IEnumerable ..然后将重复调用MoveNext和Current。
GetMyStrings()返回IEnumerable类型的对象。运行时知道如何处理它。它调用IEnumerable.GetEnumerator()然后在该枚举器对象上调用MoveNext()和Current。
只是为了解决问题,以防你落入<!>中;所有的are都是相同的<!> quot ;; for(int x = 0; x <!> lt; ProvideCeiling(); x ++) 每次 调用该函数。
不隶属于 StackOverflow