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 had explanations, and although they cleared up the situation, they didn’t make it the least bit more logical. On the contrary, I have no idea how the person who was tasked with writing these paragraphs had the self-control to not leap onto his desk, kick down his cubicle walls, pound his chest majestically and shout “DOES NO ONE HERE BELIEVE IN STANDARDS?!” before attempting to reach through his monitor, past the code, directly to the programmer who decided this was a good idea and strangle him until he reversed his decision. Although, realistically, if that did happen, the programmer would probably gasp out a quick, “This…is…Microsoft…no…standards…apply,” before passing out. The writer would then sit back down at his ravaged desk, where he would reflect on the fact that he shouldn’t have been the least bit surprised, because he works for the company that makes Internet Explorer the heinous travesty it is today.

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?

Jake is a web programmer, with a particular penchant for graphic design. In his free time, he can be found managing the array of servers under his bed, and obsessing over a single misplaced pixel.

View all posts by Jake →

  • http://twitter.com/radicalbyte Ryan Barrett

    I assume that it’s in there to “help” those poor souls described as “office developers”.

    • http://MadeByKnight.com/ Jacob Binstein

      “Just write us a quick add-in”, they said…”You’re a programmer, it shouldn’t take you too long”, they said…

  • Eric TF Bat

    Blame Visual Basic, and its OPTION BASE 1 statement.  Though why Access is different, I don’t know. Perhaps it was developed outside MS and was meant to integrate with C instead of BASIC.

    • Anonymoos

      Joel Spolsky, who used to work at Microsoft, seems to confirm your theory in his In Defense of Not-Invented-Here Syndrome” post.

  • joneholland

    Just .ToList().ToArray() it if it bothers you so much and it will be rebased to 0.

    • http://MadeByKnight.com/ Jacob Binstein

      Well, first I would have to know that the array is indeed 1-based, which I found out eventually through errors and experimentation, and only later through documentation

      • Greg Howard

         You keep referring to it as an array. As a previous poster said, it’s not an array; it’s a collection. Big difference when dealing with Microsoft APIs. It has been well documented for years that collections are 1-based. Maybe not common knowledge, but it doesn’t justify a mindless rant about Microsoft’s alleged disregard for “standards.” Arrays in MS APIs are zero-based. Collections are 1-based. It’s a fact of life. Now that you know, the challenge is to remember it when you’re writing code, just like the rest of us.

    • digler99

      “if it bothers you so much” – WTF ? anyone trained in computer science *should* be bothered by this!

  • L.

    Blame Visual Basic.

    • http://MadeByKnight.com/ Jacob Binstein

      Oh, I do =)

  • http://pulse.yahoo.com/_SAAJ6V2EF4XRXDXGZZWP5BJQCI TerrierJack

    This is silly. Everyone knows that Office arrays are 1-based. It has always been that way. It was that way long before anyone ever dreamed of C#. Since everyone knows that fact it would really be shocking if they ever decided to change it just so people born last week wouldn’t have to learn it. You’ve learned it (and made the obligatory outraged post about it) so just move on.

    • http://MadeByKnight.com/ Jacob Binstein

      But were they made long before anyone dreamed of C? I can’t think of many other languages, besides perhaps Visual Basic, in which arrays start at 1. And even if they were forced to make the arrays start at 1 for compatibility reasons, you would think that such a modification would be well-documented. Clearly not “everyone” knows that Office arrays are 1-based, nor was I born last week – as the article points out, I did my due diligence in research and failed to find the neon sign that should read “Here’s something you should know that’s non-standard.” Also, not all Office arrays are 1-based – Access is 0-based.

      • http://pulse.yahoo.com/_SAAJ6V2EF4XRXDXGZZWP5BJQCI TerrierJack

        Sorry, if you didn’t know this then you were born last week. C had nothing ever to do with Office VBA and Access is not exactly VBA.  Visual Basic did long before .Net but the decision to use 1-based arrays had more to do with people’s ideas of “easy” back then than with pure language issues. Fashions come and go but the facts remain and the fact is that Office arrays are 1-based and the earth moves in a more or less counterclockwise direction about the Sun. Don’t expect either fact to change.

        • http://MadeByKnight.com/ Jacob Binstein

          My birthday and the heliocentric nature of our galaxy notwithstanding, not everyone has your apparently intimate knowledge of Microsoft’s project history. But Microsoft knows that, so they made a few tutorial pages, none of which mentioned any of what you just said. Furthermore, only some Office arrays are 1-based, so that statement does not have the factual certainty you’ve attributed to it.

          • http://pulse.yahoo.com/_SAAJ6V2EF4XRXDXGZZWP5BJQCI TerrierJack

            Seriously, be happy, because when I learned the fact that all Office arrays are 1-based (and Access predates the Office VBA so it doesn’t count) I could not even make an internet post on it and proclaim my outrage. All I could do is wander around the office and mumble curse words.

          • Dogs

            That’s really cool! I’d like to learn more about how your life was bad and therefore everyone else sucks! 

          • http://pulse.yahoo.com/_SAAJ6V2EF4XRXDXGZZWP5BJQCI TerrierJack

            You apparently lack the chip for irony or humor. Please upgrade before you are decommissioned.

          • Lolz

            You’re a moron. Just sayin’.

          • Rick Herwig

            TerrierJack, you are truly a smug and pretentious arse. I know they say don’t feed the troll, but I’m happy to throw you a bone and say that some people know about the indexing at 1 issue. Still, to act like everyone and their grandma know about it (not to mention that it isn’t just Access with the exception, but a host of other objects, too) is not only untrue, but willfully ignorant. The reality is that this is the kind of thing that isn’t easy to find documented, but something shared by a mentor or helpful person…neither of which you seem to qualify as.

          • DaveInDunwoody

            TerrierJerk is an ass, idiot, and smug.  To expect anything less is foolish.  Move along people, just one more fool…

          • Steve Murphy

            Your inability to express your anger “back in the day” should not, in any way, limit the OP’s ability to point out a somewhat confusing element of C#. Further, upon discovering this anomaly, he attempted to spread the word in a way that did not make him appear as a though he were a pretentious ass. 

            You, evidently, felt that wandering around your cubicle, swearing, was more important. Which, to be fair, was probably the best you could do, as you claim you didn’t have access to blogging. 

            Basically, what you’re doing is analogous to approaching an author of a book and claiming that since you know the subject, that he shouldn’t bother writing the book and everyone else should figure it out for themselves because you did. This thinking is incredibly backwards, and forces people to re-do the work of others because those others wouldn’t just tell them out of some bizarre egotism. 

            Also, I’m pretty sure you’re a troll. But I had too much fun writing this to let it go to waste.

        • digler99

          but the “facts” don’t remain. MS changes, “upgrades”, and increments version numbers on their shitty products every other month.  “silverlight” anyone ? J++ anyone ? helloo ?

      • JackOfAllTrades

        When VB became VB.Net they changed the default base of arrays to 0 to be consistent with the rest of .NET .  Office uses VBA which is VB6 and antedates VB.Net .

    • http://www.facebook.com/profile.php?id=538526372 Justin LeClair

      Do you enjoy being an ass? Does it make you feel superior? Or is it just a mask for a crippling need for affirmation and attention?

      Sorry, we don’t magically inherit knowledge from previous generations. I know, with all this fancy new technology, that it seems like we’re psychic, but we’re not. Everybody doesn’t know, and when it isn’t properly documented (in true MS fashion), it is hard for us to know.

      But since you knew about this, and we obviously didn’t, that must mean you’re a better person than us, right? Because, I mean, everybody knows about it. You must have been programming before it was cool.

      At any rate, just because it has always been this way is never an excuse for it to continue to be this way. If it is wrong, it needs to change. Of course, I understand wrong is a relative thing, but lacking explanation as to why something is right or wrong, adhering to standards that have existed since programming began might be, I don’t know, better?

      But what really miffs me is the fact that you are acting indignantly offended over a tiny point that other people very obviously don’t know. The fact that I now know this (I work in open-source environments almost entirely, so I don’t know MS standards very well), may have saved me an hour or two of “WTF?” in the future, and given that, I personally thank the author for making this post.

      Also, your mother smells of elderberries and you should get the fuck off the internet, in my opinion, because it seems to bother you, but what more should I expect from yet another Yahoo user?

      • Keith Thompson

        “At any rate, just because it has always been this way is never an excuse for it to continue to be this way. If it is wrong, it needs to change.”

        Not breaking existing code is a pretty good reason not to change something.

        I’m not defending the original decision (though there is some precedent for it; see Fortran) or the lack of documentation.

      • http://www.selectioneffect.info/ Corrie Engelbrecht

        Perhaps you should simply try reading documentation, instead of waiting for your magical inheritance, or spouting some ignorant vitriol: http://msdn.microsoft.com/en-us/library/office/ee814735.aspx#odc_office14_ta_AddingVBAProgrammingToYourOfficeToolkit_VBAProgramming101

        I’m not even search for more. That was the first hit on Google.

        All Items[] properties, and anything in VBA, always starts with an index of 1. This is common knowledge to anyone who’s ever developed anything in COM, VBA, or interfaced with anything using VB. And it’s also properly, and amply documented.

        In addition to this, you can also use foreach, which is the actual reason for this requirement (but which restriction is not present in all languages), and then you don’t have to worry about it.

      • Stephan Van der Merwe

        So much fail.

    • Tom Swirly

      > Everyone knows that Office arrays are 1-based. 

      I don’t.  I’ve been programming professionally for 30 years, by the way.

      In particular, if they are going to do something that almost NO other programming language does – why don’t they make it really clear in the documentation?

      “Legacy” might justify keeping 1-based arrays – it certainly doesn’t justify not prominently documenting them.

    • Narud Shiro

      Instead to use counters, I prefer foreach (C#) or For Each (VB and VBA) to iterate over a collection or an array (which is a kind of collection too), to avoid the index base issue :-)

  • Guest

    You do realize that any collection can be overridden in .NET to be indexed starting at any number right?  That [] is just an operator?

    Also, this is simply because the objects used by Office are backed by COM objects.  These COM objects were designed for use from Visual Basic, VBScript and other languages which all have 1 based arrays.  In fact, C# did not even exist when these APIs were designed.

    • digler99

      nobody cares about legacy COM bullshit. you should have studied something useful instead of learning that garbage. parroting back bullshit is bullshit.

      • Guest

        Such intense viritol is also bullshit. Just saying.

    • Tom Swirly

      > You do realize that any collection can be overridden in .NET to be indexed starting at any number right?  That [] is just an operator?

      Consider reading the article before posting!  You’d have learned that he is getting this array given to him from the API, so he has no choice as to what its indexing is.

      There are several important points.  One is that 1-based indexing is stupid, and that’s why almost none of the many language invented before and after “COM” use it.  The other is that if you’re going to do something non-standard and confusion, you should prominently document it!

      • Guest

        It returns a Collection and [] is an operator to access its objects. The API defines these Collections whichever the way it likes. Stop whining, read the docs and use the damn API. 

  • http://twitter.com/chauvitroll Nicolas Anatoljewits

    I agree that the inconsistency is crap,
    still I find counting beginning at 1 to be more intuitive and natural.
    Also it is more useful want to get the last item in a list?
    Just do selection[size(selection)]

    • http://MadeByKnight.com/ Jacob Binstein

      I agree, I only like the 0-based ones now because I’m so used to it. As I recall, it took some getting used to. But I’d still want it consistent regardless of which they chose

    • Graham

      Working for another large software company, developing in Java here, I’m always the one who argues for Consistency amongst our APIs even where it might leave the new API slightly worse than it could be. I argue that an API that is consistent with how we’ve done things elsewhere, but is slightly uglier because of that is *better* than an API that is slightly cleaner but works differently to how the same kind of thing is done elsewhere. Depressingly, this often falls on deaf ears…

  • Jimmy Lee

    I’ve been coding only for about a year, and I thought this was common knowledge….

    • digler99

      no, the “common knowledge” is that arrays are 0-based. languages that don’t are non-standard.

      • Mark

        What about ANSI Fortran 77 which defines 1 as the start of an array as the standard?

      • Guest

        err, as mentioned several times, it’s not an array, it’s a collection… are you paying attention?

  • digler99

    don’t use C# or .NET, it’s not a standard language, it’s a Micro$oft language which will come out next year with a new version number and pricetag with both subtle and overt changes that made your previous training and code useless and incompatible. They alter the standards for the purpose of developer lock-in, because they are insecure about their own products. If they did something standards-compliant, someone could take that knowledge and use it to further an OS that isn’t virus and spyware infested.

    • Zac

      They also come out with a free version that anyone can use. Additionally, they release documentation related to that version that is quite beneficial, if you take the time to educate yourself. Where you see “subtle and overt changes that made your previous training and code useless and incompatible” I see product improvement and a chance to increase my own knowledge. I would never hire someone with your attitude.

      • digler99

        really, I can “use” it ? umm, no I can’t. See, my windows install hid all my desktop icons and documents, and now it wants me to pay for some rogue “antivirus” in order to give them back to me. Where is this ‘feature’ documented in Win7 ? I didn’t find anything of the sort, did not authorise this change, and now I can’t use my computer at all. Was the MALWARE that plagues the last 5 versions of windows (spanning the last 12 YEARS!) also part of their “product improvement and chance to increase my own knowledge” ?  You wouldn’t hire someone like me ? maybe it’s because I already have a fucking job that pays me $104,000 / yr doing real fucking software engineering with reliable tools and a stable platform. Go fuck yourself.

        • j b

          He already said he would never hire you. You need not provide further proof.

        • TheRooster

          “hid all my desktop icons and documents, and now it wants me to pay for some rogue “antivirus” in order to give them back to me”… Where did get your installation media? buy it off of some shady character in a dark parking lot out of the back of his van? does it say “Pirated in China? somewhere on the disc? or did you download it of of some FOSS site?

          And as far as “used the computer for a basic purpose for which it was designed (no “tweaking” or modifying it). ” you must be one very overpaid software engineer. I’ve never known ANY engineer who didn’t ‘tweak’ their system. Heck, I don’t think that I’ve ever known even the most basic user who didn’t change a setting on their system.You are truely unique.

          BTW, Mr “Real Software Engineer”, where did you get your degree? online?

    • Pedro

      Wrong. C# is, and has always been, an ECMA Standard.

      Please get your facts right before saying such stupid things.

      http://www.ecma-international.org/publications/standards/Ecma-334.htm

  • Matthew

    I agree with TerrierJack, this concept is pretty basic to grasp…

  • Pingback: Why Can’t Microsoft Count to 0? » GoRAL Soft

  • jostein

    Does anyone remember 16-bit Windows? System functions used the Pascal based call convention. The original Mac OS was written in a variant of Pascal. In Pascal, an array may run from index 1970 to 2012. Or from May  to August (which, by the way, is NOT from 5 to 8 or from 4 to 7).

    When writing software for real people (as opposed to programmers…) you may choose to program in the concepts of the problem space as seen by the user, or to map the user’s concepts to your own. 99 out of 100 real people call the first element in a row “the first element”, not the zeroth. If you ask them to number things, they start at one. You can model it that way. Like you can model the months as Jan, Feb, … rather than 1..12, or 0..11 as a C programmer would insist on. But they are not numbers! It is meaningless to calculate Feb times two (would that be Mar or Apr?)

    If you insist on mapping everyting into your programmer-oriented concepts, then you’ll have to fight this everlasting problem of “Have I done the mapping, or haven’t I?” If anyone believes that is a trivial question, look at HTML: Is that ampersand followed by “gt;” a literal ampersand or the escape character for a character entity? If that is a trivial problem, why do we see character entities in web pages all over? Similary with other escapes, like n.

    Similar to insisting on arrays starting at 0, you could argue that since variable length C data tends to use null termination, elements of value 0 should be illegal. In Pascal (again!), variable length stirings were usually implemented by a ‘Current length’ field (and, incidentally, with a ‘Max length’ field to prevent indexing out of bounds), but I guess C programmers would detest anything like that – it is not the way we are used to in C!

    Maybe we should insist on being Real Programmers all the way, All the C way. Like not recognizing our friends’ names unless written in the correct case. Tearing down all sorts of fences, but let everybody go everywhere. Adding apples to oranges, or even multiplying apples by oranges. And so on. I am sure we could even change the rules for naming people to use underscores between the name parts so that the full name would appear as if it were a single token. Because that is the way C has been since day 1. …Oh, sorry: Since day 0.

    • Exolon

      I’ve also been bitten by the discrepancy when calling Excel via COM from
      AutoIt, a Basic dialect which has zero-based arrays, although the first
      element by convention often holds the number of elements.

       I’m not sure it really makes sense to try to talk about arrays – or perhaps more accurately, collections of objects – in the “real user” domain.
      We use these indices to navigate arrays in a predictable fashion, so if I call a function which returns an array of things, I (hopefully) know what it means when I refer to element 0 or element 1 or element things.length()-1.

      Having my program fail to compile, or worse, crash after release, because my code disagrees with your code’s idea of where the array begins is kind of a disaster. I’d like to be able to write programs that operate on simple, flat data structures without having to worry about this.
      I’m a fan of the Lua language for its speed and simplicity, but it’s one of those “array might start at January” languages, using (hash)tables for everything. So far it hasn’t been a huge problem, but who knows – it’s one other source of discovery-at-runtime-maybe bugs.

  • Logan Venter

    Lots of TROLOLS here I see. :-)

  • Jan Ku?era

    Hello,

    seems you overlooked the fact that there are no arrays involved in the code. All documentation on arrays is correct and they behave as expected, but you are working with collections, not arrays. There are no guarantees not only that 0 is a valid index, but neither that valid indices forma  continuous sequence, for example.
    While collections have the Count property, arrays have the Length property to further emphasize this difference.
     
    Also note that checking the documentation for objects you are using instead of arrays, for example by hitting F1 on the Items property, brings you straight to the indexing fact: http://msdn.microsoft.com/en-us/library/office/microsoft.office.interop.outlook.items.aspx (even more visible for the type of the collection http://msdn.microsoft.com/en-us/library/office/microsoft.office.interop.outlook.items.aspx)

    Hope this helps and good luck in your next work!
    Jan

    • Ron Lewis

      There is so much to document in Microsoft Products. I think in most cases, the information exists within Microsoft documentation (including Help, Online Help, Walkthroughs, Videos, and more), but beginners misread it, or miss it, or have difficulty finding it. An expert reverts to beginner level when away from a product or task for several years. So, I think we need some Microsoft innovation to develop some  new way to document how to accomplish everything. When we develop and need an answer, we want the answer in a minute or two. Often we may spend hours or days trying to get an enabling answer. There should be room for improvement (i.e. shortening the time from question to answer).

      I assume Microsoft wants to attract new users to its products. How else can you grow sales? A new user will invariably be a beginner.

      So, I think it makes sense for Microsoft to seek BEGINNER’s experiences with their documentation to study beginners and how to help beginners become intermediate users in the shortest amount of time possible.

      And I think we beginners have the same problems with other companies’ documentation, as well. I hope Microsoft will lead the way.

      • Bill Gord

        I’ve been doing this programming thing now for 45 years.  And to avoid boredom I’m often switching to a different technical focus.  So about the time I feel “expert” at something I move (or get pushed) into something else.  Where I am – at some level at least – a beginner again.  Sigh…  The accumulation of random expertise is a good thing, I guess.

        I have found that *no* company produces technical level documentation that addresses the needs of the beginner.  OK, maybe in some areas.  And some subjects have wonderful technical material produced by outside publishers.

        All the material always comes with built-in preconceptions about what you know (or what you need to know) about the field in general in order to understand the new material at hand.   This is hard on the true beginner; they simply don’t know some of the important background.  But it is almost worse for the non-beginner (I shy from the term expert on purpose); a lot of what they know is based on intuitive understanding of other fields, in short they (often innocently) assume they know things, when in fact they don’t know what they don’t know. Certainly true for me.

        Much of the framework, content and volume of Microsoft’s technical documentation is court-ordered (that may have expired, but that’s a detail).  This “prevents” them from being too much the big Gorilla against their “competitors”.  Sure, Right, Whatever.  But I promise you the other big names in the computer industry were hiding around the corner when that ruling was laid down for Microsoft.  Nobody wants to make that much detail available for inside code and interfaces and whatever; although it is perhaps available under “license” if the right amount of money is attached.  Nor do they want to spend the money for its construction and upkeep.

        There are of course good documentation “examples” set by the general open-source community.  Their behavior is not uniform nor always exemplary either.  But it is pretty good, and shortcomings are at least addressable by willing participants.

        And there are, for some subjects, excellent 3rd-party technical publications: books, white papers, blogs, and such.  There is a line of books by independent authors published by Microsoft Press; some are quite good, some are a bit of a yawn.  (I am not advertising, just making a for-example point.  There are many really good technical publishers; I won’t mention them because that *would* be advertising).

        Which all puts Microsoft in being in the odd-ball position of having about the best external technical documentation of any major (non-open source) software provider. Is there room for improvement? But of course, big-time improvement!

        Like Ron said above, I hope Microsoft leads the way in improvements to availability, accuracy, accessibility and timely-ness (they are not very good on this point) of internal technical documentation.  But then, I also hope that perhaps others might follow.  This is really an industry problem, although open-source typically does it somewhat better.

        Too much rambling for one morning…
        Bill

  • http://twitter.com/jcdickinson Jonathan C Dickinson

    It’s because of VB, by the way. Remember that Office Extensibility has roots in VB5. Unfortunately this means that programs written in VB should ‘just work’ by binding to the new API – so now we have this mess. There is a method to the insanity. (By the way, that’s why there is the GetLowerBound() method on Arrays in .Net – for exactly these compatibility issues, if you want to avoid things like this consider using it instead of hardcoding ‘0’ when using legacy APIs).

  • Panagiotis Halatsakos

    Doesn’t that derive from vba coding in MSOffice? Anyone remembers OPTION BASE 1?

  • Mcollins

    Well the old visual basic 3, before byref and byval constants were used MS swapped them around from the industrial standard for parameters into procedures. I think it used to be zero array, then option 1 to start from 1, then redefine to start from what ever value you want, more like an enum. Over many years MS have changed things around, including server “trusted” and “trusting” users by the definition of the words and transposing around to confuse everyone. The ODBC which Borland invented, MS took it over and went through about 4 or 5 versions which were crap and then back to almost the Borland original design, which of course worked in the first place. In the documentation in various packages, it says MS invented ODBC, utter lies. Industrial standard for a Boolean, was Boolean, then MS C++ bucked the trend with Bool, even now in C# should you use bool or Boolean, I personally use Boolean, which is interchangeable with other languages, just my preference. What is this XAML everyone is talking about, WTF, when I saw what XAML was which IS JUST XML, XML is an extensible markup language, so define what you want, but XAML is plain vanilla XML, why is MS calling it XAML? Also MS office XML, MS wanted their own extensions of XML for their applications, but they don’t need to, as XML is extensible, so just define what you want, not bastardise/refining the WWW standard. We got rid of dll hell by having assemblies with unique dll’s, what Unix has been doing for years, no interface problems, what about the registry, why not have the main registry for windows and smaller registries for each application as part of the assemble, then just rebuild/repair the application registry, easy really. Why after 30 odd years of development have one thread for the whole GUI windows which keeps locking up even though we have a million times faster CPU’s, as usual, things waiting on one thread locks the whole windows up, just like loading a web browser, CD drive reading, etc, etc. Lazy programming, lazy design, lazy to follow standards, lazy API standards, lazy GUI.
     
    MS C# is basically Java, but now includes C++ operator overloading, generics, so perhaps MS is changing, although Java, didn’t do this as it was thought that these extensions to the language would cause semantic problems.
     
    Everything about MS is about LOCK IN and follow MS who knows best, but doesn’t. Even windows 95 interface, was exactly like the BBC Archimedes first 32bit micro processor’s interface. But the Archimedes had an acorn in the system tray which brought up a system screen to dynamically allocate more or less memory usage to any application, dynamically adjust screen resolution without reboot or seeing if monitor would support the resolution or not, add buffer screens dynamically for animations, all of this by slider control instantly. This brings me onto the marketing tactics of MS to knock out competition, another story in it own right.

    • Sande

      I don’t think there is any problem with MS taking existing technology and changing names etc. If they are trying that and its making them money then its fine by me. We can compare M$ stuff to the alternatives as you have done, but I think in their minds they will be thinking they want to make it easy for people to use (most of the time) hence why Windows has a huge installed base compared to Linux which is probably a better OS.
      All companies use marketing tactics to knock each other out. And lately we see Apple use the courts to gain competitive advantage.

  • BC_Programming

    As another commenter said, these are collections, not arrays. This might seem a trivial detail, but typically, indexing into a collection is not a good idea, because it usually isn’t performant. With Arrays, indexing numerically makes perfect sense, since (particularly in C) it’s as simple as adding the size of the element multiplied by the index to the pointer location of the array itself. Collections, however, are not necessarily represented contiguously in memory and do not always get the same benefits. Using something like:

    Object temp = explorer.CurrentFolder.Items.First();

    should get you the first element regardless of the indexing scheme implemented by the
    underlying implementation. This also has the advantage of working on any Enumerable, to
    my recollection.

  • Tom Cook

    I also spent many hours tearing my hair out over this one.  What you have discovered is that C# runs on top of the common language runtime.  While arrays created in C# are always 0-based, the CLR has support for arrays with arbitrary bounds on either end.  So, when you’re handed an array created by something other than C#, it could well have a base index that is not 0 – and not necessarily 1 either!

    I agree, whoever built the office .NET interface should have translated the arrays to 0-based in the stubs.  But they didn’t.

  • Tomz

    Unfortunately, inconsistency always exists not only in Microsoft products but also everywhere else. The only defense is to be careful when developing solutions.

  • http://www.facebook.com/kahunapig John Wilbur

    I always liked 1 to n based arrays. It made more sense than finding the first item in the zeroith position, and the nth in the nth rather than the nth-1.  for i = 1 to n: looping has always been easier (for me ) than for ( i = 0; i< n). Besides, using (gasp) Visual Baisc, I almost always had a use for array(0), holding some array related singular value. I'd prefer all languages used 1 based arrays, though I actually do like the [ ] notation. Now, if we could just do something about that pesky semicolon; 

  • Gahayden

    Y’all are missing the most important point of all – if it were straight-forward and simple we’d be out of work. Long live differentiation

  • Risav Karna

    I might be wrong but I believe Microsoft does know how to count to 0. 
    Even a Java mail folder has message containers with index starting at 1. Java mail folder apihttp://javamail.kenai.com/nonav/javadocs/javax/mail/Folder.html#getMessage(int) 
     says this: “A Message object’s message number is the relative position of this Message in its Folder. Messages are numbered starting at 1 through the total number of message in the folder.” In essence, it is not really about an array style indexing in this particular case – in many languages. As a matter of fact, wherever relative positions are a necessity, this sort of numbering is preferred – at least in MS world. What MS does wrong quite often is that it implements such selection through [1] instead of the Java-like (1). But then that sounds like a discrepancy of a syntax not standards.

    • http://maria-berner.myopenid.com/ Maria Berner

      “sounds like a discrepancy of a syntax not standards.”True indeed. And the discrepancy comes due to the fact that Collections not Arrays are used where relative positions are relevant. Haters (and Noobs) gonna hate..

  • Ronal

    very good

  • Fred Flament

    This indexing system also reminds me of good old VB when you could decide what indexing policy you wanted to use: collection starting at index 0 or starting at index 1….
    Developpers using your library would have to know implicitly what your indexing policy (0 or 1) was set when coding / compiling your module… that also reminds me of some old language (can’t remember which one actually) that would use the item at index 0 to store the length of the collection.

    • Stephan Van der Merwe

      Pascal. Delphi still does it as well.

  • Alan8

    The rule I follow is: If the collection is visible to the user through a GUI, it’s 1-based.  If it’s visible to the programmer, it’s 0-based.  Users don’t think like programmers, and (as the article demonstrates) programmers resent being forced to think like users.

    “Microsoft — Adding unnecessary complexity to your work since 1987!”

  • GDFrank

    Office is VBA (Visual Basic for Applications) based.  VBA is its internal “macro” language.  VBA is 1 based. 

    So in fact, they are honoring the VBA standard, but allowing “0 based” languages to access the VBA internals.

    In fact, arrays can have any lower bound.  It’s often good to get the low bound before accessing the array.

  • rj

    Its called backwards compatibility Jake. That is what is driving what you see.  And if you have enough experience you know that you only mess with backwards compatibility when you are willing to anger a significant portion of your user base in a given release.. which is NEVER a wise move.

  • Sean Cullinan

    I undertstand frustration but this seems like a really long blog post on something that you probably figured out in like 3 seconds.  Code it and move on…I’m sure the blog post took longer to write than the bug did to remedy.

  • Betovsky

    Arrays in C# starts at zero, there is no exception. You aren’t working with an array but with an indexer property, like in a Dictionary.

  • sam

    I am not sure why people comment here about how ‘bad’ the blog post is and how it must have taken longer to write this post than to fix the bug. If one thinks that article is a waste of time, well, don’t read and move on. 

    I personally found the article to be nicely written with some good humor and I, like many others in the comments, did not know about this. 

    Btw, I like reading memorable articles even about small things because then I am more likely to remember a particular detail. A one line post 

    “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.”

    is not memorable and I will forget it very quickly.

    Anyway, to the author, nice job. I, like many others, appreciated your write-up.

    • http://MadeByKnight.com/ Jacob Binstein

      Thanks! This is basically what my thought process was when I wrote the post, I wanted to write up the journey from error to solution, while providing my own documentation for something that I thought was lacking on Microsoft’s part. Plus a little humor, because it helps the medicine go down.

  • Bill Gord

    Well there is the historical component to all this…

    Back in 1969 i recall being terribly frustrated to encounter ALGOL (and later PASCAL) that allowed programmers to specify an array lower bound of whatever they wanted, zero being a common choice.  What sheer insanity !! “Everybody” knows that arrays start with one, as they always have in FORTRAN, BASIC and (sorry) COBOL.

    Over various career changes and continued enlightenment in my crafting of software, I came to embrace that concept, especially in light of the PASCAL type system where the base of an array might be ‘Sunday’.

    Then enters into my world – the much revered C language.  Horrors, you *must* use a lower bound of zero !!!  How constraining !!  What kind of retro-nonsense is this ???  C of course was initially designed and used for dreadfully tiny and slow hardware, where the implementation of any lower bound other than zero was simply too expensive.  And this was even before the early PCs (which themselves had capacity and performance beyond those very early C machines).  C, as we all know in retrospect, became the starting point for many modern computer languages (C++ remains my language-of-choice, but that’s just me…).

    And now we find ourselves (or at least some find themselves) back arguing the 0 or 1 case for lower bounds.  Alas this is actually long settled.  ALWAYS check the lower bound for any array that is not of your own crafting (but even then lower-bound checking is sometimes the right thing). 

    We are well past the days of computers that run simply one language.  And those unique languages have “standards” of their own (even if they don’t come with fancy ANSI / ISO / W3C numbers) that make the interface difficult for both humans and computers.  Very little thought should be necessary to figure out that VB is a derivative of BASIC (a pre-Microsoft invention), and that C# is a derivative of C (a pre-Microsoft invention),  Poor old dotNET its trying the best to make them play well in the same sandbox.  Didn’t get it right the first time?  We’re all programmers, we seldom get it all “right” the first time!  Fortunately, or we would *all* be writing FORTRAN or COBOL still.

    I’m not supporting Microsoft (directly).  Just asking that we all think about how this issue really came to be.  And that it is bigger and older than is perhaps visible in our stressed-up, day-to-day work.  Where I work (a very non-Microsoft type place) we occasionally still run into engineers or customers that forget (or perhaps never knew) the issues of inter-language compatibility.  Doesn’t mean the problem hasn’t been long known and the solution long understood.  Just means that they have to move along to a higher understanding.

    Bill

    • http://MadeByKnight.com/ Jacob Binstein

      This is absolutely fascinating. I’m definitely going to be checking the upper and lower bounds from now on…thank you for commenting!

      If you don’t mind me asking, given that you have so much experience with various languages, what makes C++ your language of choice?

      • Bill Gord

        My career path took me from assembly language, to FORTRAN, to ALGOL, to PASCAL with necessary side trips into LISP, (SNOBOL – gaak, APL – mega-gaak), COBOL, and RPG (another gaak).  In the early PC days I was a champion of Pascal (the UCSD Pascal variety available on the Apple II).  But I really struggled with Pascal’s concept of “pointers” – not intuitive (to me) and not really useful (to me); I think this is related to my assembly language background. 

        So when the early C compilers became available (for the early PC clones) I gave one a try for my hobby programming.  And fell in love with the overall generality and simplicity… Back to assembly-level control of the program without the mind-numbing tedium of machine instructions.  Caused another “career shift” as I moved into programming professionally with C. 

        And in the process of that line of work, I ran into early C++.  It was still a pre-processor to the C language and had many faults, both conceptual and in its implementation.  But it solved a number of technical things I was struggling with.  Essentially I had been simulating some of the power of “objects” by hand coding them in C (do not try this at home, it too is not good for your sanity !!).  (I forgot to mention that I had done some early contract work (while still in school) with Xerox PARC (the LISP stuff above) – so when SMALLTALK was published, I leaped onto the books and devoured them entirely).

        And all of my hobby projects have been C++ since then.  And simple “object” concepts have been factored into the environment where I program professionally (and simple objects are “good enough” for me.  Although I dabble with multiple inheritance, that too is not good for one’s sanity).

        In modern times I have had to dabble with PHP (an “ok” language, good enough for what it is intended for), JavaScript, and the whole family of HTML / CSS languages.  But that’s a minor part of my hobby stuff and it is not (in general) an area that I have much fun with. 

        And Java is sitting out there waiting for me… I may never get there or I may be pushed into it (and “they” are trying).  So don’t take my choice of C++ as any reflection on Java as I have no basis for comparison.

        Bill

  • Dan Sutton

    It has to do with backwards-compatibility to old VB applications: most VB programmers liked OPTION BASE 1 as a default; in order to maintain compatibility with those old plug-ins and so forth, they had no choice.

  • Obermd

    VB (not dotNet) one bases all collections.  Access was the exception as Access Basic wasn’t developed by the same team that developed Visual Basic.  What’s even worse for Outlook interop is that the collection can change while you’re referencing it.  This is why Outlook’s API documentation recommends using MoveFirst/MoveNext until the MoveNext returns false or Nothing.  The VB Collection iterator assumes, just as IEnumerable in dotNET, that the collection won’t change while being accessed.

  • Lucas

    Microsoft has had this problem for a while.  Note than in Visual Basic the following occurs:
    Declaring a fixed-array
    Dim numbers(5) As Integer
    The above declaration creates an array with 6 elements, with index numbers running from 0 to 5.

  • http://www.facebook.com/joequincy Jon Peterson

    [Insipid insult directed at either the author or one of the existing comment writers, or maybe even a future comment writer.]

  • Aurelia Pozniak

    Well, that is not exacly right. Arrays are 0-based, while collections are 1-based.
    One more thing – arrays don’t exacly have to be 0-based…. you can declare something like:
    Dim Arr(-100 To -51) As Long
    Although strings are allways 1-based, even though you would think that’s an array.

    • Aurelia Pozniak

       I found some source which explains how it works exacly:

      Dim Arr(10) As Long

      declares an array of either 10 or 11 elements. Note
      that the declaration does not specify the number of elements
      in the array. Instead, it specifies the upper bound of the array.  If your
      module does not contain an Option Base statement, the lower bound is assumed to
      be zero, and the declaration above is the same as
      http://www.cpearson.com/excel/vbaarrays.htm

      So by default, arrays are 0-based.

  • ??? ?????? ????

    Whoever/They (at microsoft) were hoping that the admin assistant aka secretary of the CEO of the company I work for would be able to automate some of the email task using visual basic.

    As you know secretaries don’t like counting to start from Zero. They almost demand programmers to start counting from 1.