Why Can’t Microsoft Count to 0?

I recently embarked on a project to create an add-in for Outlook 2010, using Visual Studio 2010 and C# .NET 4.0. One of the things I wanted to do was run through selected emails in order to process them.

First, I needed to know the number of items in my ActiveExplorer():

Outlook.Explorer explorer = this.Application.ActiveExplorer(); int itemCount = explorer.CurrentFolder.Items.Count;

This yielded the correct number. If I had 1 item selected, itemCount would yield 1. If I had 7, it yielded 7. Perfect.

Then it was time to actually do something with that information. As per my Intro-to-Intro-to-Computer-Science class, I attempted to access the first element of the array at index 0.

Object temp = explorer.CurrentFolder.Items[0];

Seems like it’d work, right? I mean, after all, arrays have been zero-indexed back to C. And C# is a C derivative, right? Microsoft sure seems to think so, at least as far as zero-indexing arrays go:

C# arrays are zero indexed; that is, the array indexes start at zero. Arrays in C# work similarly to how arrays work in most other popular languages.

But it didn’t work. It gave me an “Array Index Out of Bounds” error. But why?!

Just for fun, I decided to see if checking the array at index 1 would work. I had been messing around with a few other variations on the seemingly-simple line of code, and a thought occurred to me – “maybe someone at Microsoft doesn’t know that all the other arrays in this language start at 0?” So, I plugged in 1…

Object temp = explorer.CurrentFolder.Items[1];

Lo and behold, it worked. Perfectly. If there was one item in the array, it could be accessed via index 1. If there was a second item in the array, it was in index 2. There was never anything in index 0. But why?

After some lengthy research and some help from StackOverflow, I found some useful information squirreled away on Microsoft’s website. Now, if you were to do this research yourself, the obvious place to start looking would be Microsoft’s documentation on Outlook Solutions and their Walkthrough on creating your first application-level add-in for Outlook. Neither mention anything about this anomaly.

The second place you might look is through their example code, to see if they do anything which uses an array they’ve received through ActiveExplorer(). Indeed, we can see here that they use index 1 to grab the current Outlook item:

if (this.ActiveExplorer().Selection.Count > 0) { Object selObject = this.ActiveExplorer().Selection[1]; }

But that doesn’t necessarily mean anything. It’s possible that the object at index 0 exists, and is accessible, but just isn’t what they were looking for. Perhaps if the current item is in position 1, the parent folder for that item is in position 0. Perhaps if the selected item is the top-level folder, it’s parent is null, or Outlook itself. There are a number of possibilities. The fact is, that page makes no mention of the fact that they start at 1, nor a reason why.

Finally, I came upon a few pages that fairly basic explanations, but none that really satisfied the question.

Let’s look at Programming with Visual Basic vs. C# in Office Solutions. The top section is what you’d expect from a page bearing that title, a comparison between the two languages. After that, though, there’s a teeny tiny note in the Key Differences Between Office Development and Managed Code section:

To access the first item of a collection in the object model of a Microsoft Office application, use the index 1 instead of 0.

Alright, so they use some kind of weird wrapper that modifies the lower array bounds of certain collections. They made their own standard. That’s pretty annoying, and this page was really hard to find. But I guess it all works out, since they follow their own standard, right?

Wrong.

It says here that:

Most collections used in Office applications (except Access) are one-based, that is, the index number of the first item in the collection is 1. However, the collections in Access and some components, such as ADO and DAO, are zero-based, which is, the index number of the first item is 0.

So, here’s a quick summary, for those of you that need a cheat sheet. If you’re using C#, arrays start at 0. Unless you’re using C# with an Office application, because then it starts at 1. Unless that Office application is Access, a Data Access Object (DAO), or an ActiveX Data Object (ADO), because then it’s back to 0.

Simple, no?