不,不需要,因为它永远不会被使用。事实上,这是从来没有需要和应用[Guid]是一个非常糟糕的做法。
这种声明风格还有其他一些问题,讨论它们都需要我写一本书,这不是很实际。您可以更轻松地查看反编译的类型库,以便查看客户端编译器看到的内容。如果您还没有Tlbexp.exe,请使用Visual Studio Developer命令提示符生成类型库。运行Oleview.exe,文件>查看Typelib并选择.tlb文件。突出显示相关信息,您现在看到的:
importlib("mscorlib.tlb");
这是非常尴尬的,客户端程序员不只是要引用添加到您的类型库,但也为在mscorlib.dll中.NET类型库。存储在c:\ windows \ microsoft.net \ framework \ v4.0.30319目录中。或者v2.0.50727,旧版本。相当不直观,并且通常不会很好地结束。请注意,在您之前的问题中,您是如何遇到麻烦的。继续阅读,了解为什么会发生这种情况。
[
odl,
uuid(BD7A2C0E-E561-3EBC-8BB7-1C72EE61D5B0),
hidden,
dual,
nonextensible,
oleautomation,
custom(0F21F359-AB84-41E8-9A78-36D110E6D2F9, "ClassLibrary171.Car")
]
interface _Car : IDispatch {
// etc..
}
这是自动生成的“类接口”,您现在已经了解它了。这是客户端编译器实际用来进行调用的那个。请注意[uuid]属性,与C#中的[Guid]属性相同。但它有一个相当随机的价值。它是自动生成的,就像界面一样。因此,在你的声明中使用[Guid]实际上并没有完成任何事情。
[hidden]属性以及接口名称上的下划线指示类型浏览器工具(如VS中的对象浏览器)隐藏声明。使用OleView查看细节非常重要。否则,可以追溯到不支持接口,旧版本的Visual Basic(如VB6和VBA)以及脚本语言(如VBScript和JavaScript)的语言就是主要的例子。这些语言需要通过使界面看起来像一个类来模拟它们,这就是为什么你会考虑暴露类的唯一原因。
[
uuid(83F622B9-74F4-4700-9167-52C4CE9E79AA),
version(1.0),
noncreatable,
custom(0F21F359-AB84-41E8-9A78-36D110E6D2F9, "ClassLibrary171.Car")
]
coclass Car {
[default] interface _Car;
interface _Object;
};
请注意[noncreatable]属性。类型库导出程序可以看到客户端代码无法创建Car实例,因为它没有默认构造函数。这反过来帮助Regasm.exe找出注册CLSID for Car不是必需的,这就是为什么你无法在注册表中找回它的原因。
并注意_Object
接口。因为每个.NET类都从System.Object派生出现。而且,_Car
接口还具有Object(ToString,Equals,GetHashCode,GetType)的方法,因为它们继承了它们。这是你最终依赖于mscorlib.tlb的依据。他们可能可能对客户端程序员有用,但这并不常见,你通常不希望必须记录它们。你揭露的越少越好。
长话短说,这是因为您使用ClassInterfaceType.AutoDual
。这是一种方便,但不是很好的方式,微软强烈反对,推荐使用ClassInterfaceType.AutoDispatch。但这只对脚本语言有用。
您可以通过显式声明ICar
接口来避免这一切,而不是让类型库导出程序为您生成它。它需要[ComVisible(true)],并且类需要实现它。现在你可以使用ClassInterfaceType.None
。
现在你可以给接口一个[Guid]。但要小心这是不好的做法,COM要求接口是不可变的。一旦你暴露一个人,你永远不会再改变它。非常重要的是,COM有一个令人讨厌的DLL Hell问题,它是由机器范围内的注册引起的,并且您通常无法保证可以重新编译客户端程序。崩溃这可能会导致很难诊断。如果你不得不改变它,那么界面需要一个新的[Guid],所以旧界面和新界面都可以共存。通过简单地完全省略属性来完成最简单的事情,CLR已经自动生成它。使用[Guid]确实可以创建与旧界面声明二进制兼容的界面,但这很难正确执行。
您的工厂看起来像什么? – stakx
我不认为这是相关的,但我已经更新了与工厂 – peval27