Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
634 views
in Technique[技术] by (71.8m points)

c# - Please explain why I am able to instantiate the "Application" interface in Excel VSTO

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?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...