2010-08-08 8 views
5

foreach 문 안에 LinkedList 컨테이너에 노드를 안전하게 추가 할 수 있습니까? while 루프를 사용하면 어떤 차이가 있습니까? 아니면 절대 허용되지 않으며 몇 가지 문제가 발생할 수 있습니까?LinkedList에 노드 추가 foreach

foreach(var node in myList) 
{ 
    if(condition) 
     myList.AddLast(new MyNode()); 
} 

항상 일 것인가?

답변

6

컬렉션을 열거하는 동안 컬렉션을 수정할 수 없습니다. docs for LinkedList<T>.GetEnumerator에서

:

열거 컬렉션이 변경되지 유효 한 로 남아있다. 컬렉션이 변경된 경우 요소를 추가, 수정 또는 삭제하는 등의 열거자는 으로 복구 할 수 없게 무효화되고 해당 동작은 정의되지 않습니다.

실제로 나는 공식적으로 정의되지 않은 동작에도 불구하고 항상 InvalidOperationException을 던질 것이라고 생각합니다.

편집 : 당신은 while 루프 ... GetEnumerator/MoveNext/Current는 않을 것 사용하여 while 루프를 도울 것이라는 의견에 질문,하지만이됩니다

LinkedListNode<MyNode> current = myList.First; 
while (current != null) 
{ 
    if (condition) // use current.Value to get the value 
    { 
     myList.AddLast(new MyNode()); 
    } 
    current = current.Next; 
} 

를 지금까지 내가 해요로 그것은 전적으로 안전하고 예측 가능합니다. 노드에 항상 다음 노드를 요청할 수 있습니다. 꼬리 노드를보고 다른 노드를 추가하면 "다음"을 요청할 때 새 꼬리 노드가 생성됩니다.

그래도 도움이되지 않는다면 달성하려는 목표에 대해 자세히 알려주세요.

+0

새로운 노드가 조건과 일치하면 완전히 안전합니다. 스트레치, 무한 루프 및 OOM입니다. –

1

foreach 문을 사용하여 컬렉션을 반복하는 동안 수정할 수 없습니다. 따라서 항목을 추가하면 컴파일러 오류가 발생합니다.

+0

'while'루프가 내 문제를 해결할 것입니까? –

+1

'while' 루프를 사용하여 컬렉션을 반복 할 수 있습니다. 이 작업을 수행 할 때 컴파일러 오류가 발생하지 않지만 무한 루프를 작성하지 않도록주의하십시오 - 새로운'MyNode()'가'condition'을 충족 시키면 발생할 수 있습니다. –

+3

* 컴파일러 오류가 발생하지 않습니다. 주어진 코드는 문제없이 컴파일됩니다. 실행시 예외가 발생합니다. –

2

아니요, 열거 자 개체는 소유 컬렉션의 내부 버전을 기억합니다. 수집이 수정 된 후 - 버전이 변경되어 foreach가 실패합니다.

+0

+1 열거 자들이 수표를 어떻게 구현했는지 보려면 반사경을 들여다보아야합니다. :) – Ani

0

아마도 새 목록에 추가 할 수 있습니다. 그런 다음 마지막에 외부을 사용하여 .addrange()을 사용하여 새 목록을 원래 목록에 추가합니다.