16

每个 .net 开发人员都知道属性的概念。粗略的 99.99%,它只是将两个方法(getter 和 setter)粘合在一起的一段元数据。

同样的事情通常也适用于事件,包括它们的 add、remove 和 invoke 方法。

ECMA-335 描述了一种 «Other» 方法语义,适用于属性或事件。从概念上讲,一个属性或一个事件可以有多个“其他”方法。

今天是我第一次偶然发现一个带有“其他”方法的属性。当然,它必须与 COM 有关。EnvDTE 程序集(用于将插件写入 Visual Studio)中的接口 EnvDTE.Property 包含定义如下的属性:

.property object Value()
{
  .custom instance void [mscorlib]System.Runtime.InteropServices.DispIdAttribute::.ctor(int32) = ( 01 00 00 00 00 00 00 00 ) 
  .get instance object EnvDTE.Property::get_Value()
  .other instance void EnvDTE.Property::let_Value(object)
  .set instance void EnvDTE.Property::set_Value(object)
}

将 let_Value 定义为:

.method public hidebysig newslot specialname abstract virtual 
        instance void  let_Value([in] object  marshal( struct) lppvReturn) runtime managed internalcall
{
  .custom instance void [mscorlib]System.Runtime.InteropServices.DispIdAttribute::.ctor(int32) = ( 01 00 00 00 00 00 00 00 ) 
}

显然,VBScript 和 VB.NET 之前的 VB 版本可以使用 Let 关键字定义属性。Let 与 Set 具有相同的签名。我感觉这里有关系。

但是有谁知道这个属性是如何用 EnvDTE 编写的语言声明的?如何创建具有相同模式的程序集(不使用 ilasm,这太容易了)?有没有人遇到过类似的财产?

有没有人见过其他的“其他”属性,可能与这个不同的语义?如果是,他们习惯什么?

4

2 回答 2

21

这是一个在 VB 中出现的 COM 事物。Set分配一个引用来替换属性的引用项,而Let预期将操作数的内容复制到现有属性中。(另请参阅属性获取)。

IIRC 这不是核心 COM 的东西,更多的是在语言没有足够的表达能力以足够精确的程度处理价值与参考问题的情况下使用的东西——我相信它可能只适用于你使用 IDispatch (你在哪里' 是通过属性 id 而不是方法寻址)而不是自定义接口(您总是必须解析为一个方法并调用它)。我很确定 VB.NET(或其他 .NET 语言)不会出现这样的东西,因此它们是一种罕见的东西。

Essential COM by Box 没有提到它(只有 propget 和 propput 用于 get 和 set)。Al Major 博士的 COM IDL 和接口设计在 P106 上提到它,回答说:

dispinterface DMyInterface { methods:
...
[id(3), propputref] void lMyProp([in] IDispatch *pDisp);
}

propputref属性是一个奇怪的小东西,它起源于 Visual Basic 语法的特性。考虑以下:

Dim val as DMyOtherInterface
Dim var as DMyInterface

Set var.lMyProp = val
var.lMyProp = val

这两个任务都是允许的,但意味着完全不同的事情。Set在第一个 assginment 中使用关键字表示正在为 lMyProp 分配一个接口 [...]。第二个分配是一个简单的分配,其中对象的值,即接口的默认成员的值(默认成员是由ID 标记的成员,稍后将解释),被分配给接口的属性。valDMyOtherInterfaceDISPID_VALUElMyPropDMyInterface

第一个赋值使用与 lMyProp 属性关联的 propputref 方法执行,而第二个赋值使用 propput 方法。为了使其工作,必须定义propputref和propput 方法。如果您对这种做事方式感到困惑,那么您并不孤单。虽然 VB 有许多从根本上改变了编程性质的优秀特性,但该语言的定义主要是市场驱动的,而不是设计出来的,有时它显示.

有趣的是,自从 2000 年初在 COM 和 .COM 破产之前读过这本 Major 书后,我就再也没有使用过它(尽管它的目的是一本好书)。感谢您的记忆之旅——我喜欢人们告诉我们编程越来越难的方式!

我没有 Lidin 的书,看它是否提到.other,但我相信你有(顺便说一句,非常感谢 Mono.Cecil)

于 2009-12-03T14:43:30.200 回答
2

Visual Studio 自动化基于 COM。有问题的属性可能是通过支持 COM 互操作的工具生成的(tlbimp潜力)。我怀疑有人用实际的.Net 语言编写过这个代码。

于 2009-12-03T14:46:48.167 回答