假设我有以下代码:
foreach(string str in someObj.GetMyStrings()) { // do some stuff }
会someObj.GetMyStrings()在循环的每次迭代中被调用吗?最好改为执行以下操作:
someObj.GetMyStrings()
List<string> myStrings = someObj.GetMyStrings(); foreach(string str in myStrings) { // do some stuff }
?
该函数仅调用一次,以返回IEnumerator<T>; 之后,使用MoveNext()方法和Current属性来迭代结果:
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巧妙地实现了该工作。
IDisposable