我有一个托管程序集,包含几个类,而且这些类都有重载的方法。我通过以下方式向COM/idis补丁调用方公开程序集
[ComVisible(true)]..and还在程序集本身上设置正确的Guid。我没有为COM互操作定义显式接口。一切都是动态的。我在托管DLL上运行regasm.exe /codebase,并将其注册为COM互操作。
当我运行OleView时,我可以看到程序集中各个类的ProgId。但是,浏览这些ProgIds,并展开IDispatch节点,这些类没有TypeLib信息。
即使如此,我仍可以从脚本中调用接受零参数的方法或接受一个参数的方法。如果还存在接受多个参数的重载,则不能按名称调用该方法。我经常犯的错误是
Microsoft VBScript runtime error: Wrong number of arguments or invalid property assignment: <methodname>由此,我了解到COM /IDis补丁客户端无法正确解析通过COM互操作公开的对象上的重载方法。
然后我又说
[ClassInterface(ClassInterfaceType.AutoDual)]...to所讨论的每个类。在DLL上的regasm.exe之后,我可以在IDispatch节点下看到每个方法的类型信息。
我发现重载的方法会自动获得包含附加后缀的名称。MethodX将在自动生成的类型化程序集中公开重载,如MethodX、MethodX_2、MethodX_3等。
我发现,通过引用带有这些后缀的方法名称,我可以调用重载的方法,尽管不是用通用的名称。
更有趣的是,如果然后从类中删除[ClassInterface(ClassInterfaceType.AutoDual)],我仍然可以以这种方式调用重载的方法,从而避免Wrong number of arguments or invalid property assignment错误。
我的问题是:这种行为--在成员名后面添加数字后缀--稳定吗?有案可查?可靠吗?
发布于 2009-08-15 02:04:24
COM不支持方法重载,所以.NET COM互操作层不得不即兴发挥。我不确定是否像您所描述的任何地方记录的名称损坏,但即使是这样,我也不认为使用它是一个好主意-它仍然是相当不方便的API COM用户。如果您想将类公开给COM,最好的方法是编写一个独特的COM友好的[ComVisible]接口,并隐藏类本身。以COM友好的方式处理重载的正确方法是有一个带有一些[Optional]参数的方法(并委托给相应的.NET重载)。
发布于 2009-08-15 01:40:10
在我的经验中,互操作生成Method、Method_1、Method_2等是正常和稳定的,但并不是很理想。过载不跨越托管/非托管边界,这是很烦人的。与其让它任意地向我的方法添加数字后缀,我还试图将COM可见的方法重构为具有唯一名称的单独方法,这样对COM使用者来说,调用的内容就更明显了。
发布于 2012-10-25 09:11:37
是的,它被记录在MSDN上:
因为更改它将是文档特性的“突破性更改”,我想您可以依赖于它是“稳定的”。最大的缺点是您的方法名称取决于源文件中定义它们的顺序。
但是请注意,COM支持可选参数,因此使用它们可能是重载的可行替代方案。如果您需要添加重载以使其与库的旧.NET客户端兼容,我发现以下模式非常有用:
// used for binary-compatibility with .NET clients who currently use
// the old, one-parameter version
[ComVisible(false)]
void myMethod(String oneParameter) {
...
}
// since this is the first COM-visible version, it is assigned the "correct" name.
void myMethod(String oneParameter, int newParameter = 0) {
...
}因为COM支持可选参数,所以myMethod(string)和myMethod(string, int)都可以工作。
https://stackoverflow.com/questions/1277740
复制相似问题