Visually Located

XAML and GIS

Using extension methods to iterate ArcGIS COM collections

I’m a big fan of .Net and all the glory that it offers. So when I’m developing against ArcGIS COM objects I cry a little inside. Working with COM objects in .Net is not fun. C# 4.0 made this a little better by improving the code generated by interop.

Example code to get an indexed property within .Net from a COM object with VS2008

int fieldIndex = 2;
IRow row = cursor.NextRow();
object value = row.get_Value(fieldIndex);

Example code to get an indexed property within .Net from a COM object with VS2010

int fieldIndex = 2;
IRow row = cursor.NextRow();
object value = row.Value[fieldIndex];

Notice the difference? It’s in the last line where we get the value for the field. Not only do you not need the get_XXX prefix, but you use square brackets. It’s actually an indexed property now! Small things like this make working with ArcObjects a little better, but there is still a lot more that can be done. One area that always just plain sucks is iterating over COM collections. Here is a simple example of iterating over an ICursor

ICursor cursor = table.Search(null, true);
IRow row = cursor.NextRow();
while(row != null)
{
    // Do some stuff
    row = cursor.NextRow();
}

This is one of the easier COM collections to work with. This one at least does not have a Reset() method. Without a doubt, you are bound to forget that setter at the end of the while loop and your be looking at the same row for a very long time. This is very error prone.

Luckily we can add new functionality to any object by using extension methods. I hope you’re familiar with extension methods. I’m always surprised when I find active developers that have never heard of them. By creating an extension method, I can change the code above to:

ICursor cursor = table.Search(null, true);
foreach(var row in cursor.ToEnumerable())
{
    // do some stuff
}

Ahhh… So much better! No need to worry about setting the row object again at the end of the while loop. I can work with this a lot easier than before, and it just looks a ton better!

Let’s take a look at what it would take to write this extension method.

public static class Extensions
{
    public static IEnumerable<IRow> ToEnumerable(this ICursor source)
    {
        if (source != null)
        {
            IRow row = source.NextRow();
            while (row != null)
            {
                yield return row;
                row = source.NextRow();
            }
        }
    }
}

I have this code written once and I can now forget all about it! From now on it’s .Net goodness baby!

But wait! There’s more! I went ahead an created a NuGet package that contains many of these extension methods!

PM> Install-Package ArcGISExtensions

This package contains 15 ToEnumerable methods to help out with iterating over the ArcGIS COM collections. I picked the ones that are used the most. I plan to add some more Enumerable extensions as well as others to help out with your ArcGIS development.

Enjoy!