22

foreachC# ではどのように正確に実装されていますか?

その一部を次のように想像します。

var enumerator = TInput.GetEnumerator();
while(enumerator.MoveNext())
{
  // do some stuff here
}

しかし、私は実際に何が起こっているのかわかりません。enumerator.Current各サイクルの返品にはどのような方法が使用されていますか? [サイクルごとに] を返しますか、それとも無名関数または本体を実行するために何かを必要としforeachますか?

4

2 に答える 2

30

いいえ、匿名関数は使用しません。基本的に、コンパイラはコードを、ここで示した while ループとほぼ同等のものに変換します。

foreach は関数呼び出しではありませんfor。ループやループと同じように、言語自体に組み込まれていwhileます。何かを返したり、何らかの関数を「取る」必要はありません。

foreach興味深いしわがいくつかあることに注意してください。

  • 配列を反復処理する場合 (コンパイル時に認識される)、コンパイラはループ カウンターを使用して、配列の長さと比較することができます。IEnumerator
  • foreach最後にイテレータを破棄します。IEnumerator<T>which extendsの場合は簡単ですIDisposableが、そうでIEnumerator ない場合と同様に、コンパイラはチェックを挿入して、イテレータが実装しているかどうかを実行時にテストします。IDisposable
  • 適切なandメンバーを持つ型を返す適切なメソッドがある限り、IEnumerableorを実装しない型を反復処理できます。コメントに記載されているように、型はorを明示的に実装することできますが、 /以外の型を返すpublic メソッドを持つことができます。例については、を参照してください。これにより、多くの場合、参照型オブジェクトが不必要に作成されるのを回避できます。IEnumerable<T>GetEnumerator()CurrentMoveNext()IEnumerableIEnumerable<T>GetEnumerator()IEnumeratorIEnumerator<T>List<T>.GetEnumerator()

詳細については、C# 4 仕様のセクション 8.8.4 を参照してください。

于 2012-06-24T16:32:55.173 に答える