2011-09-12 4 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 (이 내 테스트 애플 리케이션에서 어떤 일이 일어나고) 다음은 InvalidOperationException이 던졌습니다, 그러나으로 VisualStudio는 " '수율 수익을 불평 때문에 나는 시도/캐치에서 foreach 루프를 포장 할 수없는 foreach는 동안 변경되는 경우 '문을 try/catch 블록에 표시 할 수 없습니다.'

어떻게 예외를 처리 할 수 ​​있습니까?

+0

실제로 예외를 처리해야합니까? 나는 그것을 처리하지 않고 발신자에게 거품을 내도록 두지 않는 것이 가장 분명한 행동이라고 생각합니다. – LukeH

+0

@LukeH 좋은 지적입니다. 아마도 잘못된 문제를보고있을 것입니다. – Grokodile

답변

3

열거자는 컬렉션이 수정 된 경우 유효하지 않아도됩니다. 표준 동작은 열거 형의 중간에 컬렉션이 수정되면 다음에 MoveNext이 호출 될 때 열거자는 InvalidOperationException을 throw합니다.

나는 InvalidOperationException을 전파시키는 것이 올바른 행동이라고 믿습니다. 열거자는 모든 표준 컬렉션 클래스와 동일한 의미를 가지므로 클래스의 소비자는이를 기대할 것입니다.

반복하는 동안 클래스 소비자가 목록을 변경해야하는 경우 색인 값을 사용하여 반복하고 목록을 수정할 때 필요에 따라 인덱서를 변경해야합니다.

1

yield returntry...catch에있을 수는 없지만 반환 할 값을 가져 오는 동안 예외를 catch 할 수는 없습니다.

예 :

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

예외가 컬렉션이 변경되었음을 표시하는 경우

, 당신 것보다는 당신이 열거에서 더 이상 항목을받지 않습니다 같은 항목을 건너 뛰는 것보다 루프 밖으로 그러나 종료합니다.

catch하는 각 예외 유형에 적절한 조치를 결정해야합니다. 일부 상황에서는 예외를 자동으로 처리하는 것이 논리적 일 수도 있지만 대부분의 경우 예외를 버블 링해야합니다. 그렇지 않으면 문제를 더 잘 설명하는 경우 다른 예외를 throw해야합니다.

관련 문제