関数の結果をループするときにforeachはどのように機能しますか?

StackOverflow https://stackoverflow.com/questions/1632810

  •  06-07-2019
  •  | 
  •  

質問

次のコードがあるとします:

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 ++) 毎回関数を呼び出します

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top