我有一个 COM 组件,其中包含 get_XXX 和 put_XXX 方法。我在一个 .NET 项目中使用了它,并为它生成了一个 RCW。我现在看到 get_XXX 和 set_XXX 方法,而不是 put_XXX 方法?这是自动的还是在 IDL 中的某个地方定义的?
2 回答
这些是属性访问器方法。使用 COM 服务器的编译器应在客户端程序读取属性时生成对 get_Xxx() 的调用,在写入属性时生成对 put_Xxx() 的调用。C# 根本没有的一个特殊方法是 putref_Xxx(),用于明确访问对象而不是值。
Tlbimp.exe 执行的正常转换是作为一个普通的 C# 属性。但这并不总是有效,C# 对属性的外观更加严格:
- 默认属性,即注释为 DISPID_VALUE (dispid 0) 的属性必须采用单个参数才能兼容。这映射到C# 索引器属性,它使您看起来像是在索引一个数组。
- 任何其他属性都不能带参数,C# 不支持索引器以外的索引属性。
- C# 没有 putref_Xxx() 的等效项,由于前两个项目符号,在 C# 程序中不会出现语法歧义。C# 团队决定实施这些限制的核心原因是,他们非常不喜欢语言中的歧义。
因此,Tlbimp.exe 被迫处理这些限制,如果 COM 属性访问器不兼容,那么它必须退回以将它们公开为普通方法而不是属性。使用默认名称,他们将获得get_
andset_
前缀。后一个解释了您的问题,他们没有选择put_
其他不清楚的原因。
值得注意的是,C# 版本 4 放宽了其中一些限制,最重要的是使与 Office 程序的互操作更容易。委婉地说,这在早期的 C# 版本中是相当痛苦的。它扩展了属性语法以减轻痛苦,但仅适用于 COM 互操作。如果您仍然停留在旧版本的 .NET 上,强烈建议您现在考虑更新。
属性本身必须有前缀(put_
等),它们有名称、getter 方法、setter 方法,但没有前缀。从类型库生成的方法表接收前缀以区分 getter 和 setter,因此有前缀。前缀字符串完全取决于生成名称的人的偏好。
也可以看看:
#pragma
import
属性 -raw_property_prefixes
默认情况下,低级 propget、propput 和 propputref 方法由分别以 get_、put_ 和 putref_ 前缀命名的成员函数公开。这些前缀与 MIDL 生成的头文件中使用的名称兼容。