请解释为什么我能够在 Excel VSTO 中实例化“应用程序”接口

本文关键字:应用程序 实例化 VSTO 接口 Excel 为什么 解释 | 更新日期: 2023-09-27 18:37:18

我的应用程序中有以下 C# 代码,运行良好。 它将启动一个新的 Excel 实例。

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

我最近才注意到应用程序是一种接口类型。 到底是怎么回事,怎么可能?

请解释为什么我能够在 Excel VSTO 中实例化“应用程序”接口

编译器

允许您实例化接口,如果它们使用 CoClass 属性进行修饰,该属性标识实现它们的具体类(以及ComImportGuid)。当您实例化接口时,您实际上是在后台实例化这个具体类。

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

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

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

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

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

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

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

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

因为MSDN是这样说的:

例如,下面的代码使用 Excel Microsoft.Office.Interop.Excel.Application 接口。 在运行时,它使用 Application 类实例化 Excel 应用程序对象并打开工作表。