Planning the Spontaneous

It's more than just a blueprint.

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

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

 
%d bloggers like this: