.net - let_ 属性方法的好奇

标签 .net cil

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

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

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

今天是我第一次偶然发现一个带有“其他”方法的属性。当然,它必须与 COM 有关。 EnvDTE 程序集(用于将插件写入 Visual Studio)中的接口(interface) 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,这太容易了)?有没有人遇到过类似的属性(property)?

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

最佳答案

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

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

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

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

The propputref attribute is an odd little thing that has its origins in the idiosynracies of Visual Basic syntax. Consider the following:

Dim val as DMyOtherInterface
Dim var as DMyInterface

Set var.lMyProp = val
var.lMyProp = val

The two assignments are both permissible but mean completely different things. The use of the Set keyword in the first assginment indicates that lMyProp is being assigned an interface [...]. The second assignment is a simpe one, where the value of the val object, which is the value of the default member of the DMyOtherInterface interface (the default member is the member tagged by the DISPID_VALUE ID, as will be explained shortly), is being assigned to the lMyProp property of the DMyInterface interface.

The first assignment is carried out using the propputref method associated with the lMyProp property, while the second assignment uses the propput method. In order for this to work, both the propputref and propput methods must be defined. If you're confused by this way of doing things, you're not alone. While VB has many good features that have fundamentally changed the nature of programming, the definition of the language was predominantly market-driven rather than being designed, and sometimes it shows.



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

不要随身携带 Lidin 的书,看看它是否提到 .other但我相信你会的(顺便说一句,非常感谢 Mono.Cecil)

关于.net - let_ 属性方法的好奇,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1840229/

相关文章:

c# - 在复杂度最小的数组中找到第二大数

c# - 不受信任的反序列化策略

.net - 如何拦截自定义处理的 WPF 绑定(bind)

c# - 使用异步和等待的死锁

c# - 方法实现中的正文签名和声明不匹配

.NET TypeBuilder - VerificationException : Operation could destabilize the runtime

c# - Azure WebJobs 未找到函数

c# - 为什么 localloc 会破坏这个 CIL 方法?

c# - C# 如何处理调用结构上的接口(interface)方法?

c# - C# 语句可以生成非连接的 MSIL