Любопытство метода let_ property - PullRequest
16 голосов
/ 03 декабря 2009

Каждый разработчик .net знает о концепции свойств. Грубо говоря, 99,99%, это просто кусок метаданных, склеивающий два метода: геттер и сеттер.

То же самое обычно происходит с событиями, с их методом добавления, удаления и вызова.

ECMA-335 описывает семантический метод «Другой», который применяется к как свойству, так и событию. Концептуально свойство или событие может иметь несколько других «других» методов.

Сегодня первый день, когда я наткнулся на свойство «другим» методом. И, конечно, это должно быть связано с COM. Интерфейс EnvDTE.Property в сборке EnvDTE (используется для записи надстроек в Visual Studio) содержит свойство, определенное следующим образом:

.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 до VB.NET могут определять свойства с помощью ключевого слова Let. И у Let та же подпись, что и у Set. Я чувствую, что здесь есть отношения.

Но кто-нибудь знает, как это свойство было объявлено на языке, на котором написан EnvDTE? Как я могу создать сборку с тем же шаблоном (без использования ilasm, это было бы слишком просто)? А кто-нибудь сталкивался с подобной собственностью?

А кто-нибудь видел другие «другие» свойства, возможно, с другой семантикой, чем эта? И если да, то к чему они привыкли?

Ответы [ 2 ]

21 голосов
/ 03 декабря 2009

Это вещь COM, которая появляется в VB. Set назначает ссылку для замены элемента, на который ссылается свойство, тогда как Let , как ожидается, скопирует содержимое операнда в существующее свойство. (См. Также Property Get ).

IIRC, это не основная вещь COM, а то, что используется там, где язык не обладает достаточной выразительной силой, чтобы достаточно точно справляться с проблемами значения и ссылок - я считаю, что это может применяться только при использовании IDispatch ( где вы обращаетесь по идентификатору свойства, а не по методу), а не по пользовательскому интерфейсу (где вы всегда должны разрешать метод и вызывать его). Я почти уверен, что VB.NET (или другие языки .NET) не обнаруживают таких вещей, и, следовательно, они редки.

Essential COM by Box не упоминает об этом (только пропет и проппут для получения и установки). COM IDL и дизайн интерфейса Dr Al Major упоминает об этом на 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 в первом предложении указывает, что lMyProp назначается интерфейс [...]. Второе назначение - простое, где значение объекта val, которое является значением элемента по умолчанию интерфейса DMyOtherInterface (элементом по умолчанию является член, помеченный DISPID_VALUE Идентификатор, как будет объяснено ниже), присваивается свойству lMyProp интерфейса DMyInterface.

Первое назначение выполняется с использованием метода propputref, связанного со свойством lMyProp, в то время как второе назначение использует метод propput. Чтобы это работало, должны быть определены оба метода propputref и propput. Если вас смущает такой способ ведения дел, вы не одиноки. В то время как у VB есть много хороших функций, которые в корне изменили природу программирования, определение языка было преимущественно ориентировано на рынок, а не разрабатывалось, и иногда оно показывает .

Забавно, но я никогда не пользовался книгой Major с тех пор, как прочитал ее в начале 2000 года, до COM и .COM (хотя это хорошая книга для своих целей). Спасибо за поездку вниз по переулку памяти - мне нравится, как люди говорят нам, что программирование становится все сложнее!

Не берите с собой книгу Лидина, чтобы узнать, упоминается ли в ней .other, но я уверен, что вы делаете (кстати, большое спасибо за Mono.Cecil)

2 голосов
/ 03 декабря 2009

Автоматизация Visual Studio основана на COM. Данное свойство, вероятно, было сгенерировано с помощью инструмента для поддержки COM Interop (потенциал tlbimp ). Я сомневаюсь, что кто-то закодировал это на реальном языке .Net.

...