Problems when a Method and Event name are the same when using C#

[Editors note: Blogging is slow right now because we are really heads down trying to get Beta 2 of Visual Studio 2005 ready for you.]

You may have run into this issue in Beta1 of Visual Studio 2005. I thought I might blog about it.

If you wrote this code which automates Excel in say a console application using Visual Studio 2003, it would work fine:

Microsoft.Office.Interop.Excel.Application myExcel;
myExcel = new Microsoft.Office.Interop.Excel.Application();
Microsoft.Office.Interop.Excel.Workbook myWB = myExcel.ActiveWorkbook;
Microsoft.Office.Interop.Excel.Worksheet myWS = (Microsoft.Office.Interop.Excel.Worksheet)myWB.Sheets.get_Item(1);                  myExcel.Visible = true;
myWS.Activate();

If you write the same code in Visual Studio 2005 Beta 1, you get a compile error on the last line of code:

error CS0229: Ambiguity between 'Microsoft.Office.Interop.Excel._Worksheet.Activate()' and 'Microsoft.Office.Interop.Excel.DocEvents_Event.Activate'

This error message is occurring because of a change to the C# compiler to make it more strict and to spec when it encounters an object that has a method and event name that have the same name. You can work around this error by casting to the _Worksheet interface which has the Activate method on it as shown in the example below. If you want to get to the event "Activate" instead, you have to cast to the DocEvents_Event interface instead.

Microsoft.Office.Interop.Excel.Application myExcel;
myExcel = new Microsoft.Office.Interop.Excel.Application();
Microsoft.Office.Interop.Excel.Workbook myWB = myExcel.ActiveWorkbook;
Microsoft.Office.Interop.Excel. _Worksheet myWS = (Microsoft.Office.Interop.Excel. _Worksheet)myWB.Sheets.get_Item(1);
myExcel.Visible = true;
myWS.Activate();

I have encountered this problem too when doing Outlook development. I was written a method on a class that was trying to hook the Close event of an explorer. Unfortunately, on the Explorer object, there is a Close event and a Close method. So to hook to the Close event I hadd to do some casting as shown here. The key lines of code is that I have to cast my Explorer object to an Outlook.ExplorerEvents_Event interface. Then I can use that cast object (e2 in the code below) to register an event handler.

public class EventListener
{
...
  System.Collections.ArrayList eventSinks;
...

  public void Explorers_NewExplorer(Outlook.Explorer e)
{
eventSinks.Add(e);
Outlook.ExplorerEvents_Event e2 = (Outlook.ExplorerEvents_Event)e;
e2.Close += new Microsoft.Office.Interop.Outlook.ExplorerEvents_CloseEventHandler(Explorer_Close);
}

  public void Explorer_Close()
{
...
}
}

It is possible that the C# team will provide a better fix for this issue before we ship VSTO 2005. But you should be able to get around it through creative casting. You shouldn't encounter this problem in VB.NET BTW.