暴露属性作为Variant在.NET中的Interop [英] Exposing Property as Variant in .NET for Interop

查看:151
本文介绍了暴露属性作为Variant在.NET中的Interop的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在.NET中创建一个包装类(VB.NET,因为它发生,但同样与C#相关)暴露在COM和我想包装的属性之一是一个Variant。我想我只能使用一个对象,但我得到一个错误:

I am creating a wrapper class in .NET (VB.NET as it happens but is equally related to C#) that is exposed to COM and one of the properties I am trying to wrap is a Variant. I thought I would just be able to use an Object, but I get an error:


Public Property FieldValue [vFieldID As Object = -1])As Object 不能作为属性Let暴露给COM。您将无法使用Let语句从Visual Basic 6.0中为此属性分配非对象值(如数字或字符串)。*

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.*

我的属性声明如下:

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方面的对象。是否有任何解决方法允许属性让?

My property actually returns a value from the database which can be integer, string, date, etc so it isn't an object in terms of COM. Is there any workaround to this to allow property Let?

推荐答案

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

COM Automation supports a default property, the property that has dispid 0. This is used in VB6 code to great effect, generating really compact code. A typical example is:

rs!Customer = "foo"

这是语法糖:

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

原始语句。 Recordset接口具有Fields属性作为默认属性,生成Fields接口引用。其中的Item属性作为默认(索引)属性生成一个Field接口引用。其中有Value属性作为默认属性,产生一个变体。

Three default properties being used here without being named in the original statement. The Recordset interface has the Fields property as the default property, producing a Fields interface reference. Which has the Item property as the default (indexed) property producing a Field interface reference. Which has the Value property as the default property, producing a variant.

这是非常好的。像这样的极端语法糖的价格是烂牙齿。在语句中存在语法模糊性:

Which is very nice. The price of extreme syntax sugar like this however is rotten teeth. There's a syntax ambiguity in a statement like:

Dim obj  
obj = someObject

这里的目的是什么?是否要将obj的someObject引用分配?或者,您要指定someObject的 default属性吗?非常不同的东西, obj 类型将完全不同。这在VB6中通过设置关键字解决。如果你想分配对象引用,你必须写:

What is intended here? Do you want to assign the someObject reference to obj? Or do you want to assign the default property of someObject? Very different things, the obj type will be completely different. This was solved in VB6 with the Set keyword. If you want to assign the object reference then you have to write:

Set obj = someObject

您可以省略设置或使用属性值。这是很幸运的,已经困扰着新手Visual Basic和VB脚本程序员很长一段时间。

And you omit Set or use Let explicitly if you mean to assign the default property value. That's pretty yucky and has bedeviled newbie Visual Basic and VB script programmers for a very long time.

COM自动化通过允许一个属性具有 em> setters。分别在IDL中提供 propputref ,其中propputref是分配对象的值。你也可以在IDispatch定义中看到这个,IDispatch :: Invoke()方法用DISPATCH_PROPERTYPUT和DISPATCH_PROPERTYPUTREF来区分这两个。

COM Automation implements this by allowing a property to have two setters. Respectively propput and propputref in the IDL where propputref is the one that assigns an object. You can also see this back in the IDispatch definition, the IDispatch::Invoke() method distinguishes between the two with DISPATCH_PROPERTYPUT and DISPATCH_PROPERTYPUTREF.

微软决定这种模糊性太痛苦,消除了默认的非索引属性的概念。其中幸运地也退休了Set关键字。然而这产生了一个新的问题,没有任何办法再写一个[ComVisible]类,它可以有一个类型为Object的属性,并具有接受对象引用的setter。语言语法仅允许一个setter,并且CLR中的COM互操作层缺少管道来合成两个。值得注意的是,这只是一个警告,你仍然得到的输出设置器,你只是不会得到propputref设置器。

Zip forward to VB.NET, Microsoft decided that the ambiguity was too painful and eliminated the notion of a default non-indexed property. Which blissfully also retired the Set keyword. This however produces a new problem, there isn't any way anymore to write a [ComVisible] class that can have a property of type Object with a setter that accepts an object reference. The language syntax permits only one setter and the COM interop layer in the CLR is missing the plumbing to synthesize two. Notable is that this is just a warning, you still get the propput setter, you just won't get the propputref setter. Which as far as I can tell is all you want anyway.

在VB6虚拟类中定义接口,或通过显式编写IDL并使用midl.exe编译它来定义接口确实是一个绕过警告的方式。如John Steve在此问题中所示

Defining the interface either in a VB6 dummy class or by writing the IDL explicitly and compiling it with midl.exe is indeed a way to sail around the warning. As shown by John Rivard in this question.

这篇关于暴露属性作为Variant在.NET中的Interop的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆