【发布时间】:2010-04-26 14:55:27
【问题描述】:
到目前为止,我一直使用[AutoDual] 属性修饰我想从VB6 使用的.NET 类。关键是在 VB6 环境中获得对 .NET 对象的 Intellisense。但是,前几天我在 Google 上搜索了 AutoDual,第一个答案是“不要使用 AutoDual”。
我一直在寻找关于为什么我不应该使用它的连贯解释,但找不到。
有人能解释一下吗?
【问题讨论】:
到目前为止,我一直使用[AutoDual] 属性修饰我想从VB6 使用的.NET 类。关键是在 VB6 环境中获得对 .NET 对象的 Intellisense。但是,前几天我在 Google 上搜索了 AutoDual,第一个答案是“不要使用 AutoDual”。
我一直在寻找关于为什么我不应该使用它的连贯解释,但找不到。
有人能解释一下吗?
【问题讨论】:
我找到了一种可靠的方法,既可以在 VB6 中为 .NET 对象提供 Intellisense,同时又不会破坏接口。关键是用 DispatchID 标记接口中的每个公共方法/属性。然后该类必须从该接口继承 - 方式如下。
[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; }
}
dispatch ID 为您提供了在类中移动项目的能力,此外,您现在可以向类中添加新内容,而不会破坏二进制兼容性。
【讨论】:
我想总结一下:
使用双接口的类型允许 客户端绑定到特定的 界面布局。任何变化 未来版本的布局 类型或任何基本类型都会破坏 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 发生了什么以及它是如何工作的链接:
针对 AutoDual 的警告不是 事实上,双接口不好,但 它自动生成的事实 COM 接口为您服务。那很不好。 每次 COM 接口必须 重新生成你会得到一个新的 GUID 和 潜在的新成员。如果 GUID 改变然后你得到一个全新的 就 COM 而言的接口/类 担心的。对于早期绑定,你会 每次都必须重建客户端 界面已重新生成。这 首选的方法是定义 COM 类接口显式地带有 图形用户界面。然后所有的早期绑定 客户端可以使用定义的接口 不用担心它会改变 他们在开发过程中。因此 推荐的选项是 None to tell CLR 不会自动生成它 你。您仍然可以实现对偶 如果你需要它的接口。
【讨论】: