2012-03-28 4 views
0

変更中のリストを列挙すると便利なことがあります。変更中に列挙できるリストタイプはありますか?

foreach (var item in listOfEntities) 
    item.Update(); 

// somewhere else (with someEntity contained in listOfEntities) 
// an add or remove is made: 
someEntity.OnUpdate += (s,e) => listOfEntities.Remove(someEntity); 

listOfEntitiesList<T>ある場合、これは失敗します。

コピーや単純なforループのような回避策がありますが、それぞれ違う欠点がありますが、フレームワーク(またはオープンソース)にリストタイプがあるかどうかを知りたいと思います。

+0

これは 'List 'の制限ではありません。これは列挙型の制限ですので、 'foreach'ではなく' for'を使用してください。 –

+2

@ M.Babcock:もちろん、あなたは 'for'ループを使うことができますが、それはあなたのプログラムが適切に動作することを意味するものではありません。 –

+0

@EdS。 - そのような実装があっても(間違っていることを証明するためにJon Skeetの待ち行列に入っている)、OPのプログラムが正しく動作するという保証はありません。 –

答えて

5

System.Collections.Concurrentのコレクションを見てください。そこにはリストはありませんが、コレクションの列挙子は[コレクション]のコンテンツの瞬間スナップショットを表しています。

これらのコレクションは複数のスレッドからアクセスできるように設計されているため、投稿したコードサンプルのようなアプリケーションに適しています。

+0

+1私はマルチスレッドのC#コードをたくさん書いていません、いつもそれらを忘れる。 –

+0

ありがとう、それは私が探していたものです! – laktak

+0

+1。単一スレッドの場合は、変更が必要な場合は反復前にコレクションを明示的にコピーすることをお勧めします。コレクション内に存在する可能性のあるアイテムまたは存在しないアイテムに対して反復処理が行われていることが非常に明確になります。 –

4

これは、List<T>とは関係ありません。それは列挙子の制限です。列挙子の下のコレクションの状態を変更すると、期間がスローされます。

ループを使用すると、ループが繰り返されますが、項目数が変更された後でコレクションにインデックスを付けると、論理エラーが発生します。

アイテムを別のスレッドで列挙している間に、コレクション内外にアイテムを入れ替えることはおそらく悪い考えです。私は、別のコレクションで取り除かれるアイテムを記録したり、コレクションが列挙されている間にコレクションをロックしたりしようと試みた真の方法に固執します。

私はこれを解決することは不可能な問題ではないと主張していますが、私はそれを行う簡単な方法がわかりません。

+0

ええ、彼らはそれを行うことができます... –

関連する問題