我为什么不使用AutoDual?

到目前为止,我总是使用[AutoDual]属性来装饰我想要在VB6中使用的.NET类。 关键是要在VB6环境中获得.NET对象的Intellisense。 然而,前几天我用Google搜索AutoDual,第一个答案是“不要使用AutoDual”。

我已经找到了为什么我不应该使用它,但找不到它的连贯解释。

有人可以解释一下吗?

我想这总结了一下:

使用双接口的类型允许客户端绑定到特定的接口布局。 未来版本对类型布局或任何基类型的任何更改都将破坏绑定到接口的COM客户端。 默认情况下,如果未指定ClassInterfaceAttribute属性,则使用仅调度接口。

http://msdn.microsoft.com/en-us/library/ms182205.aspx

它增加了使用auto dual属性更改该类中某些内容的可能性,这会在更改类时破坏其他人的代码。 如果让消费者能够做一些很可能在未来引起问题的事情。

下一个选项是ClassInterfaceType.AutoDual。 这也是获得早期绑定支持的快速而肮脏的方法(并使方法显示在VB6 IntelliSense中)。 但是通过改变方法的顺序或添加新的重载也很容易破坏兼容性。 避免使用AutoDual。

http://www.dotnetinterop.com/faq/?q=ClassInterface

我终于找到了关于AutoDual发生了什么以及它是如何工作的链接:

http://social.msdn.microsoft.com/Forums/en-US/csharpgeneral/thread/7fa723e4-f884-41dd-9405-1f68afc72597

对AutoDual的警告不是双接口坏的事实,而是它为您自动生成COM接口的事实。 那很不好。 每次必须重新生成COM接口时,您将获得新的GUID和可能的新成员。 如果GUID发生变化,那么就COM而言,你会得到一个全新的接口/类。 对于早期绑定,每次重新生成接口时都必须重建客户端。 首选方法是使用GUID显式定义COM类接口。 然后,所有早期绑定客户端都可以使用已定义的接口,而不用担心它在开发过程中对它们进行更改。 这就是推荐选项为None的原因,告诉CLR不要为你自动生成它。 如果需要,您仍然可以实现双界面。

我找到了一种可靠的方法,既可以在VB6中为.NET对象提供Intellisense,同时也不会破坏界面。 关键是使用DispatchID标记接口中的每个公共方法/属性。 然后类必须从这个接口inheritance – 以下面的方式。

 [Guid("BE5E0B60-F855-478E-9BE2-AA9FD945F177")] [InterfaceType(ComInterfaceType.InterfaceIsIDispatch)] public interface ICriteria { [DispId(1)] int ID { get; set; } [DispId(2)] string RateCardName { get; set; } [DispId(3)] string ElectionType { get; set; } } [Guid("3023F3F0-204C-411F-86CB-E6730B5F186B")] [ClassInterface(ClassInterfaceType.None)] [ProgId("MyNameSpace.Criteria")] public class Criteria : ICriteria { public int ID { get; set; } public string RateCardName { get; set; } public string ElectionType { get; set; } } 

调度ID为您提供的是能够移动类中的项目,此外您现在可以向类中添加新内容而不会破坏二进制兼容性。