请解释为什么我能够在Excel VSTO中实例化"应用程序"界面

Dan*_*ing 18 c# excel vsto

我的应用程序中有以下C#代码,工作得很好.它启动了一个新的Excel实例.

private readonly Microsoft.Office.Interop.Excel.Application _application;
_application = new Microsoft.Office.Interop.Excel.Application();
_application.Visible = true;
Run Code Online (Sandbox Code Playgroud)

我最近才注意到Application是一种接口类型.到底发生了什么,怎么可能?

Dou*_*las 29

如果接口使用CoClass标识实现它们的具体类(以及a ComImport和a Guid)的属性进行修饰,则编译器允许您实例化接口.实例化接口时,实际上是在幕后实例化这个具体类.

此"功能"旨在用作COM导入类型的管道.请注意Outlook Application接口如何由名为的具体类支持ApplicationClass:

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

在大多数情况下,你应该不会去运用这些属性到你自己的界面.但是,为了演示,我们可以证明编译器允许您利用这种可能性来实例化代码中的接口.请考虑以下简单示例(GUID是随机的):

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

class Foo : IFoo
{
    public string Bar()
    {
        return "Hello world"; 
    }
}
Run Code Online (Sandbox Code Playgroud)

使用上述声明,您可以创建自己的IFoo接口的实例:

IFoo a = new IFoo();
Console.WriteLine(a.Bar());
// Output: "Hello world"
Run Code Online (Sandbox Code Playgroud)

编辑:虽然jonnyGold正确地指出Excel Application实例没有CoClass在MSDN上修饰,但这似乎是MSDN的遗漏.Microsoft.Office.Interop.Excel程序集的反编译签名是:

[CoClass(typeof(ApplicationClass)), Guid("000208D5-0000-0000-C000-000000000046")]
[ComImport]
public interface Application : _Application, AppEvents_Event
Run Code Online (Sandbox Code Playgroud)