为什么使用Word定义一个这样的变量:
Dim Word As Microsoft.Office.Interop.Word._Application
OR
Microsoft.Office.Interop.Word._Application Word;
然后像这样设置:
Word = New Microsoft.Office.Interop.Word.Application
OR
Word = new Microsoft.Office.Interop.Word.Application();
应用程序与 _Application
之间的区别是什么?我怀疑一个人可能是一个班级而另一个人是一个界面,或者一个人可能是公开的而另一个是私人的,但对我来说仍然没有意义。
我希望有人可以向我解释。越多细节就越好。
答案 0 :(得分:12)
两者都是接口,Application
接口继承自_Application
接口(与ApplicationEvents4_Event
接口一起)。
那么何时使用什么?差异在MSDN中解释(强调添加):
<强> Application interface 强>
[GuidAttribute("00020970-0000-0000-C000-000000000046")]
public interface Application : _Application,
ApplicationEvents4_Event
这是一个源自COM coclass的.NET接口,托管代码需要该COM接口才能与相应的COM对象进行互操作。 使用此派生接口访问COM对象的所有方法,属性和事件成员。但是,如果要使用的方法或事件在同一COM对象下共享相同的名称,则强制转换为相应的主接口以调用该方法,并转换为最新的事件接口以连接到该事件。有关COM对象的信息,请参阅此主题。
<强> _Application interface 强>:
[TypeLibType(4304)]
[Guid("00020970-0000-0000-C000-000000000046")]
[ComImport]
public interface _Application { ... }
这是托管代码所需的COM coclass中的主要接口,用于与相应的COM对象进行互操作。 仅当您要使用的方法与COM对象的事件具有相同名称时才使用此主界面;在这种情况下,强制转换到此接口以调用该方法,并转换为最新的事件接口以连接到该事件。否则,使用从COM coclass派生的.NET接口来访问COM对象的方法,属性和事件。
实际后果
简而言之:在您的代码中使用Application
而不是_Application
,除非您必须这样做,因为方法名称和事件名称之间存在歧义。
例如,在Application.Quit
事件(在应用程序退出时触发)和Application.Quit(ref Object SaveChanges, ref Object OriginalFormat, ref Object RouteDocument)
方法(在调用时退出应用程序)之间存在这种歧义。
为了调用该方法,您可以简单地编写(例如退出而不提示保存更改):
Application.Quit(false);
但是,这可能会给您以下编译器警告:
警告3方法'Microsoft.Office.Interop.Word._Application.Quit(ref object,ref object,ref object)'和非方法'Microsoft.Office.Interop.Word.ApplicationEvents4_Event.Quit'之间存在歧义。使用方法组。
要避免警告,您可以将应用程序对象强制转换为_Application
界面:
((_Application)Application).Quit(false);
如果要订阅该事件,则需要将应用程序对象强制转换为相应的事件接口:
((ApplicationEvents4_Event)Application).Quit += OnApplicationQuit;
private void OnApplicationQuit()
{
// handle event here
}
答案 1 :(得分:9)
这是一个长篇故事,以惊人的速度。 COM使用基于超纯接口的范例。客户端应用程序只对界面成员进行调用,&#34; coclass&#34;实现界面的视图完全隐藏。所有暴露的都是coclass的指导,即CLSID。这将传递给通用的CoCreateInstance()工厂函数,它返回您要求的接口。这种隔离是COM服务器可以用任何语言编写的主要原因,它的实现细节都不可见,因此永远不会与您使用的任何语言不兼容。
然而,使用接口是早期VB版本的一个问题,与VB.NET不同,它们没有任何接口支持。因此,他们的运行时支持将其搞砸了,并使其看起来就像您正在使用类一样。在这种情况下命名为Application
。在这种情况下,该类的成员是默认接口_Application
的成员。来自默认源接口的任何连接点都将添加为事件。
_Application
中的前导下划线也是一个技巧,它告诉类型库浏览器隐藏接口。 Visual Studio中的对象浏览器没有做的事情,也许是你问这个问题的一个原因。诡计无法实现的一件事是处理实现多个接口的coclass。但是在类型设计师的注意下,他确保只为coclass提供一个默认接口和一个源接口。
类似的技巧对于给.NET程序员提供相同类型的api是必要的,确保他们也可以使用Application
并轻松移植他们的代码。这是由类型库导入器(Tlbimp)完成的,它合成了一个与coclass同名的额外接口,它的所有成员都与默认接口完全相同。
这是一个接口,VB.NET和C#编译器允许您创建它的实例。与普通界面无关。导入器也合成一个类,与coclass同名,使用&#34; Class&#34;追加。所以ApplicationClass
在这里。它实现了coclass实现的所有接口。你在VB.NET中没有实际用途,你应该避免它,因为非常理想的嵌入式互操作类型&#34;功能不支持嵌入它。但是你可能希望用F#之类的语言或者移植到.NET但却不支持接口的语言来使用它。
长话短说,_Application
是来自类型库的实际界面。但你应该赞成合成的Application
,与你遇到的所有代码样本最匹配。