79

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?

pnuts
  • 54,806
  • 9
  • 74
  • 122
Jon Skeet
  • 1,261,211
  • 792
  • 8,724
  • 8,929
  • 6
    Jon, in addition to the excellent answers being given here, I would add that, in general, when working with Excel through the interop, use the class name as it normally appears in Excel. This means use 'Worksheet' instead of '_Worksheet', and use 'Application' instead of 'ApplicationClass'. (A discussion here explains why not to use the 'ApplicationClass': http://blogs.msdn.com/ptorr/archive/2004/02/05/67872.aspx.) If you are not familiar with the Excel object model as exposed to COM, then this could be trickier, but I think it should be pretty clear most of the time. – Mike Rosenblum Jun 27 '09 at 01:00
  • Fortunately I'm doing *very* little with Office - really just trying to show the new features. Thanks very much for the link though - very helpful! – Jon Skeet Jun 27 '09 at 05:47
  • I'm sorry but have to ask - What is the new feature of C# 4 that you are highlighting? – Oskar Jul 09 '09 at 15:40
  • For this particular case it was dynamic typing - the return types of various method calls/properties are effectively "dynamic", hence the lack of casts which would otherwise be required. – Jon Skeet Jul 09 '09 at 16:12

5 Answers5

77

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.

Eric Lippert
  • 612,321
  • 166
  • 1,175
  • 2,033
  • It's Worksheet/_Worksheet we're talking about here... you made the same misreading as JP, but as he points out, the situation is basically equivalent. ;) – Noldorin Jun 26 '09 at 22:27
25

If you look at the PIA assembly (Microsoft.Office.Interop.Excel) in Reflector, the Workbook interface has this definition ...

public interface Workbook : _Workbook, WorkbookEvents_Event

Workbook is _Workbook but adds events. Same for Worksheet (sorry, just noticed you were not talking about Workbooks) ...

public interface Worksheet : _Worksheet, DocEvents_Event

DocEvents_Event ...

[ComVisible(false), TypeLibType((short) 0x10), ComEventInterface(typeof(DocEvents),
                     typeof(DocEvents_EventProvider))]
public interface DocEvents_Event
{
    // Events
    event DocEvents_ActivateEventHandler Activate;
    event DocEvents_BeforeDoubleClickEventHandler BeforeDoubleClick;
    event DocEvents_BeforeRightClickEventHandler BeforeRightClick;
    event DocEvents_CalculateEventHandler Calculate;
    event DocEvents_ChangeEventHandler Change;
    event DocEvents_DeactivateEventHandler Deactivate;
    event DocEvents_FollowHyperlinkEventHandler FollowHyperlink;
    event DocEvents_PivotTableUpdateEventHandler PivotTableUpdate;
    event DocEvents_SelectionChangeEventHandler SelectionChange;
}

I would say it's best bet to use Worksheet, but that's the difference.

Noldorin
  • 134,265
  • 53
  • 250
  • 293
JP Alioto
  • 43,483
  • 5
  • 85
  • 112
8

Classes and Interfaces for Internal Use Only

Avoid directly using any of the following classes and interfaces, which are used internally and are typically not used directly.

Class/Interface : Examples

classid Class : ApplicationClass (Word or Excel), WorksheetClass (Excel)

classid Events x _SinkHelper : ApplicationEvents4_SinkHelper (Word), WorkbookEvents_SinkHelper (Excel)

_classid : _Application (Word or Excel), _Worksheet (Excel)

classid Events x : ApplicationEvents4 (Word), AppEvents (Excel)

I classid Events x : IApplicationEvents4 (Word), IAppEvents (Excel)

http://msdn.microsoft.com/en-gb/library/ms247299(office.11).aspx

edit: (re: formatting of this answer) cannot correctly format an escaped underscore followed immediately by italic text. Shows correctly in preview but broken when posted

edit2: works if you make the underscore itself italic which is conceptually horrible but looks the same I suppose

Community
  • 1
  • 1
barrowc
  • 9,773
  • 1
  • 34
  • 49
7

I have seen and written quite a bit of C# / Excel COM Interop code over the last few years and I've seen Worksheet used in almost every case. I have never seen anything definitive from Microsoft on the subject.

Joe Erickson
  • 6,836
  • 1
  • 29
  • 31
  • Thanks. Out of interest, have you been keeping up with the improvements in C# 4? They *sound* like they'd make a big difference in terms of Office interop, but without the experience I'm really just guessing (aka bluffing, when it comes to writing the book...) – Jon Skeet Jun 26 '09 at 22:09
  • The dynamic / COM Interop improvements look useful when you have to use COM, but I am pretty sure I will not use the dynamic feature for much more than that. The things I'm really looking forward to are in C# 4 / .NET 4 are code contracts and Task Parallel Library. – Joe Erickson Jun 26 '09 at 22:17
6

MSDN shows that the Worksheet interface simply inherits from the _Worksheet and DocEvents_Event interfaces. It would seem that one simply provides the events that a worksheet object might raise in additional to everything else. As far as I can see, Worksheet doesn't provide any other members of its own. So yeah, you might as well just go with using the Worksheet interface in all cases, since you don't lose anything by it, and potentially might need the events it exposes.

Noldorin
  • 134,265
  • 53
  • 250
  • 293
  • 5
    Jon Skeet *asking* a question?? I had to take this rare oppurtunity to respond! :) – Noldorin Jun 26 '09 at 22:20
  • (In addition, I might just choose to use Worksheet because that underscore looks awfully ugly there... But seriously, there seems no reason not to do so.) – Noldorin Jun 26 '09 at 22:29