2011-08-24 2 views
0

예를 들어foreach 루프에서 쿼리 수집이 변경된 이후에 오류가 발생해야합니까?

  var query = myDic.Where(x => !blacklist.Contains(x.Key)); 
     foreach (var item in query) 
     { 
      if (condition) 
       blacklist.Add(item.key+1); //key is int type 
      ret.add(item); 
     } 
     return ret; 

이 코드가 유효합니까? 어떻게 개선 할 수 있습니까?

업데이트 됨

blacklist.add(item.key+1)ret이 작을 것으로 예상됩니다. ToList() 방식은 이러한 의미에서 내 의도를 달성하지 못합니다. 에는 정확하고 모호하지 않은 다른 더 좋은 아이디어가 있습니다.

+0

예.콜렉션 내부 객체를 변경하는 것은 콜렉션을 반복 할 때 엄격히 금지됩니다. – RLH

+1

'blacklist'에 항목을 삽입하면 'blacklist'의 업데이트 된 내용이 후속 루프 반복에 영향을 주어야합니까? –

+0

@Anthony Pegram : 나는 그렇게 희망한다. – colinfang

답변

2

반복 작업을 수행하는 컬렉션을 직접 수정하지 않으므로 완벽하게 안전하며 아무런 문제가 없어야합니다. 비록 당신이 인데, where 절에 영향을주는 다른 변경 사항은 여러분에게 날아 가지 않을 것입니다.

질의 (쿼리 작성)는 느리게 평가되므로 컬렉션을 반복 할 때 blacklist이 업데이트되므로 모든 후속 반복은 목록에서 새로 추가 된 항목을 반복하여 볼 수 있습니다.

위의 코드는 효과적으로과 동일합니다 :

foreach (var item in myDic) 
{ 
    if (!blacklist.Contains(item.Key)) 
    { 
     if (condition) 
      blacklist.Add(item.key + 1); 
    } 
} 

그래서 당신이 나가야 것은 그만큼 당신이 직접이 후 (항목을 통해 반복되는 컬렉션을 수정하지 않는 한 inforeach 루프), 당신이하는 일은 안전합니다. 당신은 여전히 ​​확신하지 않는 경우

이 생각하고 무엇을하면 콘솔에 기록 될 것입니다 :

var blacklist = new HashSet<int>(Enumerable.Range(3, 100)); 
var query = Enumerable.Range(2, 98).Where(i => !blacklist.Contains(i)); 
foreach (var item in query) 
{ 
    Console.WriteLine(item); 
    if ((item % 2) == 0) 
    { 
     var value = 2 * item; 
     blacklist.Remove(value); 
    } 
} 
2

예. 콜렉션 내부 객체를 변경하는 것은 콜렉션을 반복 할 때 엄격히 금지됩니다.

내가 처음 여기 코멘트를 만들었지 만,

UPDATE는 정보의 추가 비트 :

내 지식은 경험과 기사에서 온다 내가 오래 전에 읽은 있음을 유의

. 쿼리에 블랙리스트 내의 선택된 객체에 대한 참조가 포함되어 있기 때문에 위의 코드를 실행할 수 있습니다. 블랙리스트는 변경할 수 있지만 쿼리는 할 수 없습니다. 블랙리스트를 엄격하게 반복한다면 블랙리스트 컬렉션에 추가 할 수 없습니다.

+2

이것은 맞지만 반복 컬렉션을 변경하지 않으므로 코드가 정확합니다. –

2

제시된 코드는 예외를 발생시키지 않습니다. 반복되는 컬렉션 (myDic)은 수정되는 컬렉션이 아닙니다 (blacklist 또는 ret).

루프의 각 반복은 쿼리 항목에 대해 현재 항목을 평가하여 blacklist 컬렉션에 현재 항목의 키가 들어 있는지 확인합니다. 느리게 평가되므로 한 번에 blacklist으로 변경하면은 이후의 반복에 영향을 줄 수 있지만 오류는 발생하지 않습니다. (blacklist은 반복 될 때마다 완전히 평가되므로 해당 열거자는 보유되지 않습니다.)

+1

마지막으로 올바른 대답입니다. :) –

관련 문제