为暴露给COM的.NET类定义接口有什么好处?

时间:2011-04-26 03:33:06

标签: .net com

我正在构建一个需要从VBA引用的库,所以我需要提供一个类型库来支持早期绑定。我见过的大多数例子都为暴露给COM的类定义了一个接口,例如。

[Guid("D6F88E95-8A27-4ae6-B6DE-0542A0FC7039")]     
[InterfaceType(ComInterfaceType.InterfaceIsDual)]     
public interface IMyClass 

[Guid("13FE32AD-4BF8-495f-AB4D-6C61BD463EA4")]     
[ClassInterface(ClassInterfaceType.None)]     
[ProgId("MyNamespace.MyClass")]     
public class MyClass : IMyClass

让类直接使用ClassInterface.AutoDual实现接口是否有任何缺点?对于更复杂的类,我喜欢使用接口来清楚地定义哪些成员公开com而无需在任何地方使用ComVisible属性。但是我还会有很多相当简单的数据类,比如事件args,它们将完全暴露给COM。我还看到了在接口上明确设置dispid的示例 - 这样做有什么好处吗?

1 个答案:

答案 0 :(得分:5)

是的,有一个很大的问题:DLL Hell是讨厌的与早期绑定。 COM客户端通过v表指针直接调用该方法。如果使用相同接口IID(其本身就是犯罪)的过时COM服务器是驻留的,那么这可能会调用错误或不存在的方法。运行时故障(通常是AccessViolation)很难诊断。

后期绑定不会发生这种情况,(通常)会有一个合理的诊断,例如DISP_E_MEMBERNOTFOUND或DISP_E_BADPARAMCOUNT。这就是微软非常看好ComInterfaceType.InterfaceIsIDispatch的原因。缺点是后期绑定非常慢。另一个问题是错误只在运行时捕获,而不是在编译时捕获。

设置DispID很少有用。一些传统的Microsoft产品使用dispid绑定,将dispid预编译到代码中。它大约是后期绑定的两倍,因为不需要IDispatch :: GetIDsOfNames()调用。你不太可能在野外遇到它们,当然不是任何VBA版本。

关于is here主题的一篇体面的知识库文章。