web-dev-qa-db-ja.com

foreachは自動的にDisposeを呼び出しますか?

C#では、foreachはIDisposableを実装するオブジェクトに対してDisposeを自動的に呼び出しますか?

http://msdn.Microsoft.com/en-us/library/aa664754(v = vs.71).aspx は、次のことを示しているようです:

*それ以外の場合、コレクション式はSystem.IEnumerableを実装する型であり、foreachステートメントの展開は次のとおりです。

IEnumerator enumerator = 
        ((System.Collections.IEnumerable)(collection)).GetEnumerator();
try {
   while (enumerator.MoveNext()) {
      ElementType element = (ElementType)enumerator.Current;
      statement;
   }
}
finally {
   IDisposable disposable = enumerator as System.IDisposable;
   if (disposable != null) disposable.Dispose();
}
58
jim

はい、foreachは、IDisposableを実装している場合、列挙子でDispose()を呼び出します。

51
Matt H

この質問/回答の言葉遣いは不十分です。

尋ねられた質問が以下であるかどうかは明確ではありません:

Q:「foreachは、次に移動する前に、列挙子によって返されたオブジェクトを破棄しますか?」

A:答えはもちろんです。列挙内の各オブジェクトに対して一度コードを実行する便利な方法を提供する以外は何もしません。

またはそれが意味するかどうか:

Q:「内部では、foreachは列挙可能なオブジェクトを使用します。これは、反復子ブロックに例外がある場合でも、foreachの呼び出し後に破棄されますか?」

A:答えは(まだかなり明白です)YESです。構文は列挙子へのアクセスを提供しないので、それを破棄する責任があります。

2つ目の質問に対する答えは、foreachがtry/finallyブロックでwhileブロックに拡張されることを人々が聞いたことがあるため、混乱が生じる場所です。最終的にその目的は、IDisposableを実装する場合に列挙子が確実に破棄されるようにすることです。

自分で確認する必要がある場合: ここで実際に確認してください

これが明確になることを願っています! ;)

12
Stuart Frost