19

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

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

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

4

2 回答 2

32

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

此“功能”旨在用作 COM 导入类型的管道。请注意 OutlookApplication接口是如何由名为 的具体类支持的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正确地指出 ExcelApplication实例没有在 MSDN 上装饰CoClass,但这似乎是 MSDN 的遗漏。来自程序集的反编译签名Microsoft.Office.Interop.Excel是:

[CoClass(typeof(ApplicationClass)), Guid("000208D5-0000-0000-C000-000000000046")]
[ComImport]
public interface Application : _Application, AppEvents_Event
于 2012-06-14T19:17:54.543 回答
-2

因为MSDN是这么说的:

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

于 2012-06-14T18:55:11.717 回答