19

I have the following C# code in my application which works just fine. It launches a new instance of Excel.

private readonly Microsoft.Office.Interop.Excel.Application _application;
_application = new Microsoft.Office.Interop.Excel.Application();
_application.Visible = true;

I only recently noticed that Application is an interface type. What exactly is going on and how is it possible?

Dan Ling
  • 2,965
  • 2
  • 29
  • 43

2 Answers2

32

The compiler allows you to instantiate interfaces if they’re decorated with a CoClass attribute identifying the concrete class that implements them (as well as a ComImport and a Guid). When you instantiate the interface, you would actually be instantiating this concrete class behind-the-scenes.

This “feature” is intended to be used as plumbing for COM imported types. Notice how the Outlook Application interface is backed by a concrete class named ApplicationClass:

[GuidAttribute("00063001-0000-0000-C000-000000000046")]
[CoClassAttribute(typeof(ApplicationClass))]
public interface Application : _Application, ApplicationEvents_11_Event

In most circumstances, you should not go applying these attributes to your own interfaces. However, for the sake of demonstration, we can show that the compiler will allow you to take advantage of this possibility for instantiating interfaces in your code. Consider the following simple example (the GUID is random):

[ComImport]
[Guid("175EB158-B655-11E1-B477-02566188709B")]
[CoClass(typeof(Foo))]
interface IFoo
{
    string Bar();
}

class Foo : IFoo
{
    public string Bar()
    {
        return "Hello world"; 
    }
}

Using the above declarations, you can create an instance of your own IFoo interface:

IFoo a = new IFoo();
Console.WriteLine(a.Bar());
// Output: "Hello world"

Edit: Although jonnyGold correctly notes that the Excel Application instance is not decorated with CoClass on MSDN, this appears to be an MSDN omission. The decompiled signature from the Microsoft.Office.Interop.Excel assembly is:

[CoClass(typeof(ApplicationClass)), Guid("000208D5-0000-0000-C000-000000000046")]
[ComImport]
public interface Application : _Application, AppEvents_Event
Community
  • 1
  • 1
Douglas
  • 53,759
  • 13
  • 140
  • 188
  • Thanks for the clear explanation. I'm now left wondering "why?", but I assume a good understanding of COM interop would be pre-requisite to that. – Dan Ling Jun 14 '12 at 19:27
  • My unsubstantiated guess is that this was a “hack” introduced into the .NET compiler purely for addressing some legacy requirements while interoperating with COM. – Douglas Jun 14 '12 at 19:31
  • According to [this](http://msdn.microsoft.com/en-us/library/microsoft.office.interop.excel.application.aspx) `Microsoft.Office.Interop.Excel.Application` isn't decorated with the `CoClassAttribute`, but it must be. Admittedly, I have not used dotPeek on the assmebly in question. – bluevector Jun 14 '12 at 19:32
  • @jonnyGold: Yes, that was the reason I didn’t paste the Excel `Application` signature for my example. Replied in answer with decompiled signature. – Douglas Jun 14 '12 at 19:42
  • Just opened it up in dotPeek and verified that Application is decorated with [CoClass(typeof(ApplicationClass))]. – Dan Ling Jun 14 '12 at 21:26
-2

Because MSDN says so:

For example, the following code uses the Excel Microsoft.Office.Interop.Excel.Application interface. At run time, it uses the Application class to instantiate an Excel Application object and open a worksheet.

bluevector
  • 3,485
  • 1
  • 15
  • 18
  • 3
    Hardly a satisfactory answer… MSDN also says “An interface cannot be instantiated directly.” – Douglas Jun 14 '12 at 19:09
  • Agreed. The article doesn't explain how that is even syntactically valid. Nor does the library documentation. – bluevector Jun 14 '12 at 19:16