関数の結果をループするときに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
}
?
解決
IEnumerator<T>
を返すために、関数は1回だけ呼び出されます。その後、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を取得するために1回呼び出されます。その後、MoveNextおよびCurrentを繰り返し呼び出します。
GetMyStrings()は、IEnumerable型のオブジェクトを再調整します。ランタイムはそれに対処する方法を知っています。 IEnumerable.GetEnumerator()を呼び出し、その列挙子オブジェクトでMoveNext()およびCurrentを呼び出します。
<!> quot; all forが同じ<!> quot;に陥った場合に質問を四捨五入するだけです。 for(int x = 0; x <!> lt; ProvideCeiling(); x ++) 毎回関数を呼び出します 。
所属していません StackOverflow