Collection was modified; enumeration operation may not execute

23 Ocak 2016 1 dk okuma süresi 120 okunma
Collection'lar tıpkı array gibi veriyi saklamak, gruplamak ve içerisinde arama yapmak veya dolaşmak için kullanılırlar fakat collectionlar arraylerden çok daha gelişmiştir.

Projelerimizde collection'ları oldukça sık kullanırız. Bazen kod akışına veya koşullara göre collection'aları modifiye etmek (ekleme, çıkarma, düzenleme vb.) durumunda kalırız. Özellikle foreach kullanarak bu işlemleri yapmaya çalışırız fakat foreach bu gibi modifiye işlerinde pek önerilmez çünkü collection üzerinde yapacağınız ufak bir değişiklikte aşağıdaki gibi bir hata alırsınız. Aşağıdaki hata collection'dan birşeyi silmek istediğinizde ortaya çıkar.

System.InvalidOperationException was unhandled
Message="Collection was modified; enumeration operation may not execute."
Source="mscorlib"
StackTrace:
at System.ThrowHelper.ThrowInvalidOperationException(...)
at System.Collections.Generic.List`1.Enumerator.MoveNext()

İlk başta ne alaka diyip hatayı okumazsınız ve bir anlam veremezsiniz fakat StackTrace'i okuduğunuzda sorunun ne olduğu apaçık ortadadır. Ufak bir kod örneği ile daha iyi anlayabilirsiniz.

Elinizde bir treeView olduğunu düşünün ve burdan bir node'u silmeniz gerekiyor. Bu durumda şöyle bir kod yazardınız.

foreach (var treeNode in treeView1.Nodes)
{
 if (treeNode.Nodes.Count == 0)
 {
  treeNode.Remove();
 }
}

Foreach sürekli bir sonraki eleman için index'i hafızasında tutar. Nasıl for döngüsünde treeView1.Nodes[i] kullanıyorsak ve i hangi sırada olduğunu belirtiyorsa foreach'te bunu hafızasında yapar. Yani şu an 2., 3. veya 20. elemandayım gibi. Ancak siz sırası gelen bir collection elemanını modifiye ettiğinizde sıra foreach hafızasından kaybolur ve hangi sırada olduğunu bilemez. Bu nedenle "Collection was modified, ..." hatasını alırsınız. Bu sadece silme değil, ekleme veya düzenleme yaptığınızda da olur. Bu nedenle collection üzerinde modifiye yapacaksanız foreach yerine for döngüsünü kullanabilirsiniz.

for (var i = 0; i < treeView1.Nodes.Count; i++)
{
 if (treeView1.Nodes[i].Count == 0)
 {
  treeView1.Nodes.Remove(treeView1.Nodes[i]);
 }
}

Foreach'i detaylı incelemek için msdn linkine göz atabilirsiniz. https://msdn.microsoft.com/en-us/library/ttw7t8t6.aspx?f=255&MSPPError=-2147217396

Yazılarıma abone olmak ister misiniz?
Spam yapılmaz, sadece bildirim amaçlıdır. İstediğiniz zaman abonelikten çıkabilirsiniz.
İlginizi çekebilecek diğer yazılar.
VS2015'in 3. update'ini yaptıktan sonra asp.net core web uygulaması yaratmak istediğimde şu şekilde bir hata ile karşılaştım. "Exception : The system cannot find the file specified. (Exception from HRESULT: 0x80070002)". Çözümü oldukça basit.

Entity framework code first kullanıyorsanız ve inheritance yapıp yeni bir class yarattığınızda bunun gibi bir hata alırsınız. Bunun nedeni fluent api'nin inheritance yapılan class ile ana class'ın map yapmaya çalışması ve ilgili kolonu veritabanında bulamamasıdır. Çözümü ise inherit olmuş class'a [NotMapped] DataAnnotations attribute'unu eklemek.

Asp.Net Mvc ile recursive nasıl yazılır, @helper veya HtmlHelper kullanarak recursive fonksiyon yazmak, Asp.Net MVC View recursive fonksiyon nasıl yazılır?