Planning the Spontaneous

It's more than just a blueprint.

Posts Tagged ‘Collection was modified’

Linq me

Posted by Robert Chow on 07/04/2010

It’s been more than a few months into my placement now, and my grasp of C# has really gone further than just ‘beginner’ now.

There is a lot of material about Linq on the Internet, and because I should have posted about it a lot earlier, I’m only just going to touch upon a small problem I had yesterday.

Linq

Linq stands for language-intergrated query and consists of a small number of extension methods allowing users to query an IEnumerable collection.   The idea is to allow similar to SQL type queries be made on a collection and are very useful.

Invalid Operation Exception : Collection was modified;

The problem I had was taking a collection, applying a filter and then using the filter to alter the original collection.  Here’s an example of the code.

var toDelete = aCollection.Take(20).Skip(10);
foreach(CollectionItem collectionItem in toDelete)
{
aCollection.Remove(collectionItem);
}

This takes a collection, and applies a filter to it using Linq. The Take(20) will take the first 20 items in aCollection.   Apply Skip(10) will then filter the result to take the remaining items after skipping the first 10 items.  In the foreach loop, I then attempt to delete the items I have filtered from the original collection.

It works fine for the first iteration, yet on the second it throws a nasty error, “Invalid Operation Exception : Collection was modified”.  I know I am modifying the original collection, yet strangely enough it is throwing the exception, expressing that I have modified the toDelete collection.  Nowhere in the loop do I touch the toDelete collection at all.

So it seems

Unfortunately, I do. The reference held by toDelete is the same reference as aCollection – modifying aCollection will also modify toDelete.   This is because when I assign toDelete, it takes the same reference as aCollection, and then includes the filters.  My first impression of using Take and Skip was that it would return a new collection, with just the filtered elements, alas, it is not to be.

Knowing this, I realise I need to take the filtered elements and recreate the filter in a new collection.  Fortunately, Linq can also help me do this.

toDelete = toDelete.ToList();

Seems a bit of a pain that the filter doesn’t actually give a new collection item. I hope that after reading this, you can also avoid similar problems as I did.

Advertisements

Posted in Computing, Placement | Tagged: , , , | Leave a Comment »