C#’ta “Collection Was Modified; Enumeration Operation May Not Execute.” Hatası ve Çözümü

Merhaba,

Yazılım dünyasının temeli ve prosedürel programlamanın has elemanlarından biri olan döngü yapıları üzerinde yapılan çalışmalarda farklı olası hatalar almanız gayet normal bir durumdur. Bu hataların onlarca farklı sebebi olabilmekle beraber, döngü kalıbının başlangıç olarak belirlediği temel değerlerle iterasyon sürecindeki değişikliklerin birbirlerine tezatlık çıkarmasından kaynaklanabilmeside muhtemeldir. İşte bizde bu yazımızda buna benzer bir durumdan kaynaklanan hata üzerine odaklanacak ve çözüm yolu sunacağız.

Hiç vakit kaybetmeden aşağıdaki örnek kod bloklarını inceleyelim ve aldıkları hata üzerine konuşalım.

            List<int> Sayilar = new List<int> { 1, 3, 5, 7, 9, 11, 13, 17 };
            Sayilar.ForEach(s => Sayilar.Remove(s));
            List<int> Sayilar = new List<int> { 1, 3, 5, 7, 9, 11, 13, 17 };
            foreach (var sayi in Sayilar)
                Sayilar.Remove(sayi);

Bu iki örnek kodumuzda maksadımız foreach döngüsünün kullanım varyasyonlarını gözler önüne getirmektir. Eğer ki bir foreach döngüsünü, döngü sonlanmadan bağlı olduğu koleksiyon içerisinden veri silerek kullanmaya çalışırsak konumuz olan hatayla karşılaşmamız oldukça muhtemeldir.

Aldığımız hata metinsel olarak aşağıdaki gibidir.

System.InvalidOperationException: ‘Collection was modified; enumeration operation may not execute.’

Bu hata biraz yukarıda bahsettiğim gibi foreach döngüsünün kullandığı koleksiyonun içeriği değiştiğinden dolayı işleme devam edilememesinin bir tezahürüdür.

Bu hatadan kurtulmanın bir kaç farklı, algoritmik temellere dayanan yolları vardır. Şimdi gelin bu yolları inceleyelim.

1. Yol
foreach değil, for yahut diğer prosedürel döngüleri kullanmanız hatayı ortadan kaldıracaktır.

            List<int> Sayilar = new List<int> { 1, 3, 5, 7, 9, 11, 13, 17 };
            for (int i = 0; i < Sayilar.Count; i++)
                if(Sayilar[i] == 3)
                Sayilar.Remove(Sayilar[i]);

2. Yol
2. yol olarak aşağıdaki gibi algoritmik çalışma yapmamız yeterli olacaktır. Burada foreach döngüsünün kullandığı koleksiyondan, asıl işlem yapılacak koleksiyon soyutlandırılmıştır.

            List<int> Sayilar = new List<int> { 1, 3, 5, 7, 9, 11, 13, 17 };
            List<int> SilinecekSayilar = new List<int>() { 1, 3, 5, 7 };
            SilinecekSayilar.ForEach(s =>
            {
                if (Sayilar.Contains(s))
                    Sayilar.Remove(s);
            });

Evet… Anlayacağınız foreach döngülerinde kullanılan kaynak koleksiyon yapılarının içerikleri oldukça önem arz etmektedir. Bir iteratör mantığıyla çalışan foreach döngüsü kaynağındaki değişim esnasında iterasyondaki devamlılığı getirmekte sorunlar yaşamakta ve bu hatayı fırlatmaktadır.

Sonraki yazılarımda görüşmek üzere…
Şimdilik hoşçakalın…
İyi çalışmalar…

Bunlar da hoşunuza gidebilir...

Bir Cevap Yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

CAPTCHA (Şahıs Denetim Kodu) Resmi

*

Copy Protected by Chetan's WP-Copyprotect.