gpt4 book ai didi

c# - 在 .NET 中将属性公开为变体以进行互操作

转载 作者:太空狗 更新时间:2023-10-29 18:01:34 25 4
gpt4 key购买 nike

我正在 .NET(碰巧是 VB.NET,但与 C# 同样相关)中创建一个包装类,它向 COM 公开,我试图包装的属性之一是 Variant。我以为我只能使用一个对象,但我得到了一个错误:

Public Property FieldValue([vFieldID As Object = -1]) As Object cannot be exposed to COM as a property 'Let'. You will not be able to assign non-object values (such as numbers or strings) to this property from Visual Basic 6.0 using a 'Let' statement.*

我的属性(property)声明如下所示:

Public Property FieldValue(Optional ByVal vFieldID As Object = -1) As Object
Get
Return _objVAccess.FieldValue(vFieldID)
End Get
Set(ByVal value As Object)
_objVAccess.FieldValue = value
End Set
End Property

我的属性实际上从数据库返回一个值,该值可以是整数、字符串、日期等,因此它不是 COM 方面的对象。是否有任何变通方法允许属性让?

最佳答案

COM Automation 支持默认属性,即 dispid 为 0 的属性。这在 VB6 代码中使用效果很好,生成非常紧凑的代码。一个典型的例子是:

rs!Customer = "foo"

这是语法糖:

rs.Fields.Item("Customer").Value = "foo"

此处使用了三个默认属性,但未在原始语句中命名。 Recordset 接口(interface)将 Fields 属性作为默认属性,生成一个 Fields 接口(interface)引用。它具有 Item 属性作为生成 Field 接口(interface)引用的默认(索引)属性。它具有 Value 属性作为默认属性,产生一个变体。

这是非常好的。然而,像这样极端语法糖的代价是蛀牙。语句中存在语法歧义,例如:

Dim obj  
obj = someObject

这里的目的是什么?您要将 someObject 引用分配给 obj 吗?还是要分配 someObject 的默认属性?非常不同的东西,obj 类型会完全不同。这已在 VB6 中使用 Set 关键字解决。如果你想分配对象引用,那么你必须写:

Set obj = someObject

如果您要分配默认属性值,则可以省略 Set 或显式使用 Let。这太令人讨厌了,长期以来一直困扰着新手 Visual Basic 和 VB 脚本程序员。

COM 自动化通过允许一个属性具有两个 setter 来实现这一点。分别是 IDL 中的 propputpropputref,其中 propputref 是分配对象的那个。您还可以在 IDispatch 定义中看到这一点,IDispatch::Invoke() 方法通过 DISPATCH_PROPERTYPUT 和 DISPATCH_PROPERTYPUTREF 区分两者。

Zip forward 到 VB.NET,Microsoft 认为歧义太痛苦,因此取消了默认非索引属性的概念。这也幸福地淘汰了 Set 关键字。然而,这会产生一个新问题,不再有任何方法可以编写一个 [ComVisible] 类,该类可以具有 Object 类型的属性和接受对象引用的 setter。语言语法只允许一个 setter,而 CLR 中的 COM 互操作层缺少合成两个的管道。值得注意的是,这只是一个警告,您仍然可以获得 propput setter,只是不会获得 propputref setter。据我所知,这正是您想要的。

在 VB6 虚拟类中或通过显式编写 IDL 并使用 midl.exe 编译它来定义接口(interface)确实是绕过警告的一种方法。如 John Rivard 在 this question 中所示.

关于c# - 在 .NET 中将属性公开为变体以进行互操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9481140/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com