2010-02-27 3 views
12

나는 사전을 사용하고 있으며 그것을 통해 열거하는 동안 변경하고 싶지만 허용되지 않는 것 같습니다. 어떻게해야합니까?.NET 사전 수정하기

감사

+0

당신이 키 또는 값을 변경 하시겠습니까? –

+1

당신이 다리 위에있을 때 다리를 다시 만들고 싶지 않을 것입니다, 그렇지? 다른 방법으로 구현하고 싶을 수도 있습니다. –

+5

@ [o.k.w] 믿거 나 말거나, 그러나 거대한 다리가 건설되고 수정/수리되는 방법입니다. 거대한 사전이있어서 각 값을 수정해야하는 경우 먼저 키를 복제하지 않는 것이 좋습니다. –

답변

5

삭제하려는 키 또는 개체를 저장하고 루프를 끊은 다음 remove 메서드를 사용하여 사전에서 개체를 삭제해야합니다.

희망이 있습니다.

1

나는의 대기열과 관련하여 그것을 here 대답하지만, 대답은 동일합니다. foreach를 사용하여 열거 할 수 없으며 동시에 컬렉션을 수정할 수 없습니다.

10

기본적으로하지 마십시오. 명시 적으로 지원되지 않습니다. Dictionary<,>.GetEnumerator()에 대한 문서에서 :

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

일반적으로 가장 좋은 방법은 변경하려는 사항을 기억한 다음 나중에 수행하는 것입니다. 또는 사전을 복사 한 다음 을 반복하여 원본을 수정하는 동안을 반복 할 수 있습니다. 당신이하려는 일에 대해 더 많은 정보를 주시면 도움이 될 것입니다.

가이 말을하는 데, .NET 4.0 의 새로운 ConcurrentDictionary 클래스 허가를 않습니다이 - 당신은 당신이 반복하는 동안 변경 사항을 볼 수 있습니다, 또는 당신은하지 않을 수 있습니다 -하지만, 반복의 결과가 보장되지 않습니다.

+1

아마 더 정확하게 그들이 ConcurrentDictionary에 대해 IllegalOperationException을 던질 수있는 좋은 방법을 찾을 수 없다는 것입니다. 그것은 많은 문제를 일으킬 것입니다. 나는 확실히 그것을 추천하지 않을 것이다. –

+1

@nobugz : 나는 IllegalOperationException을 던질 수 없기 때문에 그것이 매우 의심 스럽다. 동시 콜렉션의 핵심은 iterating을 포함하여 * 동시에 * 할 수 있다는 것입니다.이제는 반복되는 동일한 스레드에서 컬렉션을 수정하려고합니다 (피할 수있을만큼 쉽기 때문에). 그러나 일반적으로는 훨씬 더 어렵습니다. –

+0

왜 실제로는 관련이 없지만 예외가 발생하지 않는 것은 사실입니다. 복음으로 당신의 게시물을 가져가는 많은 프로그래머가 있습니다. 당신의 충고의 파급 효과를 고려할 것을 촉구해야합니다. 같은 스레드 또는 다른 스레드에 관계없이 반복하는 동안 사전을 변경하면 Heisenbug에 전체가 쓰여집니다. 반사 된 소스 코드를 보면서 ConcurrentDirectionary는 사고를 피하기 위해 아무 것도하지 않습니다. 그리고 MSDN 문서는 완전히 침묵합니다. –

1

직장에서 비슷한 상황이 발생했습니다. 나는 키/값이 남아 있지 않을 때까지 반복적으로 작게 만드는 동안 사전을 수정해야했습니다.

"제거 할"키 목록을 작성하여 시작했지만, 구현해야하는 다른 모든 논리가 너무 느립니다. 다른 방법으로, 나는 사전을 거꾸로 반복하는 것을 끝내었다. 사전을 앞뒤로 건너 뛸 때 반복은 오류를 발생시키지 않습니다. 작동과 같이 보입니다 내 일 관련 로직을 찍은 후

, 그것은 바보 보이는,하지만 난 약속 :

Dictionary<int, List<int>> dict = new Dictionary<int, List<int>>(); 
    while(dict.Any()) 
    { 
     foreach(var key in dict.Keys.Reverse()) 
     { 
      if(//conditional) 
      { 
       dict.Remove(key); 
      } 
      else 
      { 
       //do something with dict[key] 
      } 
     } 
    }