Dot-Net

let_ 屬性方法的好奇

  • May 3, 2016

每個 .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,這太容易了)?有沒有人遇到過類似的財產?

有沒有人見過其他的“其他”屬性,可能與這個不同的語義?如果是,他們習慣什麼?

這是一個在 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 標記的成員,稍後將解釋),被分配給介面的屬性。val``DMyOtherInterface``DISPID_VALUE``lMyProp``DMyInterface

第一個賦值使用與 lMyProp 屬性關聯的 propputref 方法執行,而第二個賦值使用 propput 方法。為了使其工作,必須定義propputref*和propput 方法。*如果您對這種做事方式感到困惑,那麼您並不孤單。雖然 VB 有許多從根本上改變了程式性質的優秀特性,但該語言的定義主要是市場驅動的,而不是設計出來的,有時它顯示.

有趣的是,自從 2000 年初在 COM 和 .COM 破產之前讀過這本 Major 書後,我就再也沒有使用過它(儘管它的目的是一本好書)。感謝您的記憶之旅——我喜歡人們告訴我們程式越來越難的方式!

我沒有 Lidin 的書,看它是否提到.other,但我相信你有(順便說一句,非常感謝 Mono.Cecil)

引用自:https://stackoverflow.com/questions/1840229