2011-09-12 24 views
0

私はICollectionViewによって返された各要素をとり、別のオブジェクトに変換しようとしている次のコードを持っています。foreachループ内でInvalidOperationExceptionを処理する方法yield return?

public IEnumerator GetEnumerator() 
    { 
     foreach (TOriginal original in _collectionView) 
     { 
      if (!Equals(original, null)) 
      { 
       yield return GetTranslated(original); 
      } 
      else 
      { 
       yield return default(TTranslated); 
      } 
     } 
    } 

_collectionViewは(これは私のテストのアプリで起こっている)foreachの中に変更された場合、それはInvalidOperationExceptionががスローされますが、VisualStudioのは、「「降伏リターンを文句を言うので、私はのtry/catchでforeachループをラップすることはできません'文はtry/catchブロックに現れませんでした'。

どうすれば例外を処理できますか?

+0

実際に例外を処理する必要がありますか?私はそれを扱うのではなく、それを呼び出し側にバブルさせることが最も明白な動作であると想像しています。 – LukeH

+0

@LukeHそれは良い点です、多分私は間違った問題を見ています – Grokodile

答えて

3

列挙子は、コレクションが変更されても有効である必要はありません。標準的な動作では、列挙の途中でコレクションが変更された場合、列挙子は次回MoveNextが呼び出されたときにInvalidOperationExceptionをスローします。

私はInvalidOperationExceptionを伝播させることが適切な動作であると信じています。あなたの列挙子は、すべての標準コレクションクラスと同じセマンティクスを持つので、クラスのコンシューマはこれを期待します。

繰り返し処理中にクラスのコンシューマがリストを変更する必要がある場合は、インデックス値を使用してループし、必要に応じてインデックスを変更してリストを変更する必要があります。

1

yield returntry...catchに入れることはできませんが、返される値が取得されている間に例外をキャッチすることはできません。

例:

object value; 
try { 
    value = SomeCodeThatCanBreak(); 
} catch (SomeException ex) { 
    // you could silently skip this item: 
    value = null; 
} 
if (value != null) { 
    yield return value; 
} 

あなたは列挙子のうちいずれかのより多くのアイテムを取得することはできませんように例外は、あなたはかなりの項目をスキップよりもループのうち一方の出口だろう、コレクションが変更されていることを示している場合。

catchする例外の種類ごとに、どのようなアクションを適切にするかを決める必要があります。状況によっては、例外を静かに処理するのが理にかなっているかもしれませんが、ほとんどの状況で例外をバブルアップさせるべきです。

関連する問題