I'm currently writing about dynamic typing, and I'm giving an example of Excel interop. I've hardly done any Office interop before, and it shows. The MSDN Office Interop tutorial for C# 4 uses the _Worksheet
interface, but there's also a Worksheet
interface. I've no idea what the difference is.
In my absurdly simple demo app (shown below) either works fine - but if best practice dictates one or the other, I'd rather use it appropriately.
using System;
using System.Linq;
using Excel = Microsoft.Office.Interop.Excel;
class DynamicExcel
{
static void Main()
{
var app = new Excel.Application { Visible = true };
app.Workbooks.Add();
// Can use Excel._Worksheet instead here. Which is better?
Excel.Worksheet workSheet = app.ActiveSheet;
Excel.Range start = workSheet.Cells[1, 1];
Excel.Range end = workSheet.Cells[1, 20];
workSheet.get_Range(start, end).Value2 = Enumerable.Range(1, 20)
.ToArray();
}
}
I'm trying to avoid doing a full deep-dive into COM or Office interoperability, just highlighting the new features of C# 4 - but I don't want to do anything really, really dumb.
(There may be something really, really dumb in the code above as well, in which case please let me know. Using separate start/end cells instead of just "A1:T1" is deliberate - it's easier to see that it's genuinely a range of 20 cells. Anything else is probably accidental.)
So, should I use _Worksheet
or Worksheet
, and why?
If I recall correctly -- and my memory on this is a bit fuzzy, it has been a long time since I took the Excel PIA apart -- it's like this.
An event is essentially a method that an object calls when something happens. In .NET, events are delegates, plain and simple. But in COM, it is very common to organize a whole bunch of event callbacks into interfaces. You therefore have two interfaces on a given object -- the "incoming" interface, the methods you expect other people to call on you, and the "outgoing" interface, the methods you expect to call on other people when events happen.
In the unmanaged metadata -- the type library -- for a creatable object there are definitions for three things: the incoming interface, the outgoing interface, and the coclass, which says "I'm a creatable object that implements this incoming interface and this outgoing interface".
Now when the type library is automatically translated into metadata, those relationships are, sadly, preserved. It would have been nicer to have a hand-generated PIA that made the classes and interfaces conform more to what we'd expect in the managed world, but sadly, that didn't happen. Therefore the Office PIA is full of these seemingly odd duplications, where every creatable object seems to have two interfaces associated with it, with the same stuff on them. One of the interfaces represents the interface to the coclass, and one of them represents the incoming interface to that coclass.
The _Workbook interface is the incoming interface on the workbook coclass. The Workbook interface is the interface which represents the coclass itself, and therefore inherits from _Workbook.
Long story short, I would use Workbook if you can do so conveniently; _Workbook is a bit of an implementation detail.