2010-01-04 8 views
2

닷넷 수집, MSDN states 열거 : 컬렉션이 변경되지 않고 남아있는컬렉션을 열거하고 수정 한 다음 예외를 throw하는 선례는 무엇입니까?

열거는만큼 유효합니다. 요소 추가, 수정 또는 삭제와 같이 컬렉션이 변경되면 열거자는 무의식적으로 무효화되고 해당 동작은 정의되지 않습니다.

정확히 "복구 불가능하게 무효화"된다는 것은 무엇을 의미합니까?

예를 들어 왼쪽과 오른쪽 하위 참조와 상위 참조를 모두 사용하여 이진 트리를 만듭니다. 이러한 트리에서는 트리의 단일 노드에 대한 단일 참조만으로 트리를 탐색 할 수 있으므로 트리에서 다음 노드를 쉽게 찾을 수 있습니다.

그래서이 트리에서는 다른 노드를 제거한다고 가정합니다. (아마도 현재 앉아있는 노드를 제거하지 않습니다.) 여전히 열거자를 무효화해야합니까? 여기서는 다중 스레드 작업, 루프를 실행하는 단일 스레드 및 루프 본문 내부의 컬렉션 수정에 대해 설명하지 않습니다.

이 "법"은 정말로 그 법칙입니까, 열거자인 이 계속되는 경우에도 일 수 있겠습니까?

답변

8

열거자를 계속할 수 있다고해도 실제로 "법"이라고하는 것이 사실입니까?

개인적으로 이론적으로 계속할 수 있다고해도 열거 자 던지기는 개인적으로 좋은 생각입니다.

사람들은 실수로 foreach 루프 내부에서 컬렉션을 변경하는 코드를 삽입합니다. 이렇게하지 않으면 개발자가 현재 테스트하고있는 특정 인스턴스를 던지지 않을 수 있지만 다른 런타임 조건으로 인해 쉽게 throw 될 수 있습니다.

항상 던지기 만하면 개발자는 라이브러리를 처리 할 때 놀라운 수준을 줄이기 때문에 개발자가 프레임 워크의 컬렉션 및 열거 형과 동일한 코드를 처리하도록 강요합니다.

+2

+1. 일관된 방식으로 예외를 던지는 것이 안전성은 열거 자의 위치에 따라 열거 자에게 영향을 미치지 않는 방식으로 수정 된 컬렉션에 대해 열거를 계속할 수 있다는 잠재적 이점보다 훨씬 중요하다고 생각합니다. –

+0

그건 내 생각이야 - 일관성 (특히 프레임 워크와 함께)은 가장자리의 경우에 이것을 할 수 있다는 한계 값보다 더 큰 가치가있다. –

2

표준 컬렉션 열거 자의 구현은 법으로 만듭니다. 객체를 만들면 컬렉션 객체에서 비공개 "버전"정수가 복사됩니다. 컬렉션을 수정하면 해당 버전이 증가합니다. iterator 메소드는 버전을 비교하고 불일치가 발생하면 throw합니다. 주위를 둘러 볼 방법이 없습니다.

그러나 컬렉션이 열거되는 동안 컬렉션을 수정할 수있는 컬렉션 클래스가 하나 있습니다 (Microsoft.VisualBasic.Collection). VB6 Collection 클래스와의 호환성을 유지하려면 그렇게해야했습니다. 그것이 어떻게 수행되는지보기 위해서 그것을 보길 원할 것입니다. IIRC에서는 모든 반복자에 대해 WeakReference를 유지 한 다음 컬렉션이 수정되면 반복기를 업데이트합니다. 이것은 어리석은 증거가 아닙니다. 요소를 제거하고 다시 추가하면 동일한 개체를 두 번 열거 할 수 있습니다. 그것도 저렴하지 않습니다.

관련 문제