Parameterized Properties and the Office Interop API Extensions

One of the disadvantages of C# compared with VB is its lack of support for parameterized properties. Instead, parameterized properties in C# are exposed as normal method calls prefixed with "get_" and "set_". This is particularly apparent when working with the Office object model as it exposes many such properties, the majority being indexers on collection interfaces. To make matters worse, some collection interfaces have array indexers rather than indexer properties, which make indexing inconsistent between collection types. Since many of the parameters are optional or accept varying types, we lose many of the strong typing benefits of the C# language. The end result is inconsistent, inelegant, and error prone code.

Let's take the Documents collection in Word for example. That interface defines the Item property with a single variant (i.e. object) argument. According to the MSDN documentation, that argument value should be an integer or a string. Retrieving a document by integer index looks something like:

object index = 1;

 

Word.Document doc = Application.Documents.get_Item(ref index);

 

MessageBox.Show("Name: " + doc.Name);

 

Notice the use of 1 instead of 0; remember that the Office object model uses 1-based indexing. Also note that we have to pass the index by reference, requiring an extra object on the stack. This is a particular quirk of the Word object model, but one that makes for even more inelegant code.

Retrieving a document by name looks something like:

object index = "WordDocument1.docx";

 

Word.Document doc = Application.Documents.get_Item(ref index);

 

MessageBox.Show("Name: " + doc.Name);

 

Let's clean up these examples using the Office Interop API Extensions, one of the recently released VSTO Power Tools. For collections, the libraries expose a set of common Item() extension methods with strongly-typed arguments. With those we can rewrite our examples:

Word.Document doc = Application.Documents.Item(1);

 

MessageBox.Show("Name: " + doc.Name);

 

And:

Word.Document doc = Application.Documents.Item("WordDocument1.docx");

 

MessageBox.Show("Name: " + doc.Name);

 

Unfortunately, not all of the collections could be extended in the initial release of the VSTO Power Tools. You will find the Word and Excel object models to be most complete, with key collections extended across the rest of the Office suite. (If there are particular collections which you think should be extended in the future, please let us know so that we can prioritize them appropriately.)

Indexers are not the only parameterized properties which were extended, however. Let's take another example from Excel:

Excel.Worksheet sheet = InnerObject;

Excel.Range range1 = sheet.get_Range("A1:B1", System.Type.Missing);

Excel.Range range2 = sheet.get_Range("A1", "B2");

 

In this example, we're retrieving two ranges from an Excel Worksheet. The Range property (as defined by the COM interface) accepts two parameters, both of which are of variant type and the second of which is also marked optional. Since C# doesn't support optional parameters, we have to pass System.Type.Missing to indicate the absence of the second value. Since both values are variant types, we do not have any compile-time type checking. Again, we can use the extensions provided by the Office Interop API Extensions to improve the code:

Excel.Worksheet sheet = InnerObject;

Excel.Range range1 = sheet.Range("A1:B1");

Excel.Range range2 = sheet.Range("A1", "B2");

 

Not only have we eliminated the ugly "get_" and the need to specify System.Type.Missing, our arguments are conveniently strongly-typed. These may seem like little things, but over the long term I think the improved readability and additional compile-time support will make for a better Office development experience for the C# developer.

This post was migrated from my MSDN blog, Visual Studio Tools and Anything Else I Can Think Of, and written as a Microsoft employee.

2014

Back to Top ↑

2012

Back to Top ↑

2008

Finding DASL Property Names

1 minute read

The LINQ-to-DASL provider of the Office Interop API Extensions provides a very limited set of mappings between its query types and their associated DASL prop...

Debugging LINQ-to-DASL Queries

3 minute read

When your LINQ-to-DASL queries do not return the results you expect, how do you determine where the problem is?  The issue could be that the query simpl...

LINQ to DASL Walkthrough

3 minute read

Now that the Office Interop API Extensions have been released, I thought I would post a complete walkthrough of a simple LINQ to DASL application. Let's star...

Office Interop API Extensions Now Available!

less than 1 minute read

As announced in Andrew Whitechapel’s post, version 1.0 of the VSTO Power Tools have been released! One of those tools is the Office Interop API Extensions, a...

Using LINQ with the Office Object Model

3 minute read

In my last post I talked about LINQ to DASL, a LINQ provider that converts query expressions into their DASL equivalent in order to efficiently filter item c...

Back to Top ↑

2007

VSTO at Portland Code Camp v3.0

less than 1 minute read

Yesterday I gave a presentation on VSTO at the third annual Portland Code Camp. I demonstrated an Outlook 2007 add-in that used Outlook Form Regions, WCF, an...

Back to Top ↑