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;
}
Jika Anda mengomentari for
loop dalam , itu akan terlempar, itu jelas karena kami melakukan perubahan pada koleksi.
Sekarang jika Anda menghapus komentar, mengapa loop ini memungkinkan kita menambahkan dua item tersebut? Dibutuhkan beberapa saat untuk menjalankannya seperti setengah menit (Pada Pentium CPU), tetapi tidak membuang, dan lucunya adalah ia mengeluarkan:
Itu sedikit diharapkan, tetapi ini menunjukkan bahwa kami dapat mengubah dan itu benar-benar mengubah koleksi. Adakah ide mengapa perilaku ini terjadi?
c#
collections
LyingOnTheSky
sumber
sumber
int.MaxValue
iterasi ...Jawaban:
Masalahnya adalah cara
List<T>
mendeteksi modifikasi adalah dengan mempertahankan bidang versi, jenisint
, menambahkannya pada setiap modifikasi. Oleh karena itu, jika Anda telah membuat persis beberapa beberapa 2 32 modifikasi ke daftar antara iterasi, itu akan membuat mereka modifikasi terlihat sejauh deteksi yang bersangkutan. (Ini akan meluap dariint.MaxValue
keint.MinValue
dan akhirnya kembali ke nilai awalnya.)Jika Anda mengubah hampir semua hal tentang kode Anda - tambahkan 1 atau 3 nilai daripada 2, atau turunkan jumlah iterasi loop dalam Anda sebanyak 1, maka itu akan memunculkan pengecualian seperti yang diharapkan.
(Ini adalah detail implementasi daripada perilaku yang ditentukan - dan ini adalah detail implementasi yang dapat diamati sebagai bug dalam kasus yang sangat jarang terjadi. Akan sangat tidak biasa melihatnya menyebabkan masalah dalam program nyata.)
sumber
_version
bidangnya adalahint
.InvalidOperationException
, yang sebenarnya tidak selalu benar. Tentu saja ini tergantung pada definisi "detail implementasi".