var ints = new List< int >( new[ ] {
1,
2,
3,
4,
5
} );
var first = true;
foreach( var v in ints ) {
if ( first ) {
for ( long i = 0 ; i < int.MaxValue ; ++i ) { //<-- The thing I iterate
ints.Add( 1 );
ints.RemoveAt( ints.Count - 1 );
}
ints.Add( 6 );
ints.Add( 7 );
}
Console.WriteLine( v );
first = false;
}
내부 회 for
돌이 를 주석 처리하면 , 그것은 분명히 우리가 컬렉션을 변경했기 때문입니다.
이제 주석 처리를 제거하면 왜이 루프에서 두 항목을 추가 할 수 있습니까? 30 분 (펜티엄 CPU에서)처럼 실행하는 데 시간이 걸리지 만 던지지 않으며 재미있는 점은 다음과 같이 출력된다는 것입니다.
약간의 예상 이었지만 우리가 변경할 수 있다는 것을 나타내며 실제로 컬렉션을 변경합니다. 이 문제가 발생하는 이유는 무엇입니까?
답변
문제는 List<T>
수정 사항 을 감지 하는 방법이 버전 필드 유형을 유지하고 int
수정 될 때마다 증가한다는 것입니다. 따라서 반복 사이에 목록 에 2 32 개의 수정을 정확히 몇 배로 만든 경우 검색과 관련하여 해당 수정 사항이 보이지 않게 렌더링됩니다. (에서 로 오버플로 되어 결국 초기 값으로 돌아갑니다.)int.MaxValue
int.MinValue
코드에 대해 거의 모든 것을 변경하는 경우-2가 아닌 1 개 또는 3 개의 값을 추가하거나 내부 루프의 반복 횟수를 1만큼 줄이면 예상대로 예외가 발생합니다.
(이것은 특정 동작이 아닌 구현 세부 사항이며 매우 드문 경우 버그로 관찰 될 수있는 구현 세부 사항입니다. 그러나 실제 프로그램에서 문제를 일으키는 것을 보는 것은 매우 드문 일입니다.)