В чем разница между Property Set и Property Let в VB6?

Я только что создал несколько Property Set методов, и они не компилировались. Когда я их поменял на Property Let, все было нормально.

С тех пор я изучил документацию, чтобы найти разницу между Property Set и Property Let, но должен признать, что не стал мудрее. Есть ли разница, и если да, может ли кто-нибудь предложить указатель на ее правильное объяснение?


person Brian Hooper    schedule 18.02.2011    source источник


Ответы (3)


Property Set для объектов (например, экземпляров класса)

Property Let предназначен для "обычных" типов данных (например, строка, логическое значение, длинное значение и т. Д.)

person mwolfe02    schedule 18.02.2011
comment
Он не связан с WithEvents, он предназначен для возврата ссылок на объекты как свойств. Есть много раз, когда вы хотите сделать это, чаще всего, когда у вас есть какая-либо иерархия объектов. - person Bob77; 18.02.2011
comment
Неправильный. Property Get используется для возврата объектных ссылок как свойств, а не Property Set. - person mwolfe02; 18.02.2011
comment
msdn.microsoft.com/en-us/library/aa266202 (VS.60) .aspx: Подобно процедурам Function и Property Get, процедура Property Set представляет собой отдельную процедуру, которая может принимать аргументы, выполнять серию операторов и изменять значение своих аргументов. Однако, в отличие от процедур Function и Property Get, обе из которых возвращают значение, вы можете использовать только Property Set процедуру в левой части назначения ссылки на объект (оператор Set). - person mwolfe02; 18.02.2011
comment
+1 Правильно, Property Set определяет свойство, которое можно использовать в левой части оператора Set. Я действительно думаю, что упоминание WithEvents немного сбивает с толку, на самом деле это не связано с объяснением разницы. Property Set может быть полезен для отношений 1: 1 между объектами, которые можно динамически изменять во время выполнения, то есть за пределами WithEvents. - person MarkJ; 18.02.2011
comment
Да, для настройки свойства - у меня это было на 180 градусов назад, mea culpa. В конце концов, это так же просто, как прочитать руководство, как указано выше. - person Bob77; 18.02.2011
comment
@ Боб: +1 за признание ошибки. Прошу прощения, если мой тон оказался резким, но я хотел прояснить техническую проблему. И пока мы выдаем mea culpas, я признаю, что моя первоначальная формулировка излишне запутала проблему Property Set и WithEvents. Когда я впервые узнал о классах в VB6 / VBA, у меня были проблемы с пониманием того, когда вы хотите использовать оператор Property Set. Я просто хотел дать ОП типичный пример. С моей стороны было ошибкой предполагать, что это «единственная» ситуация, в которой Property Set может быть полезен. Надеюсь, новая формулировка станет более ясной. - person mwolfe02; 18.02.2011

Property Let более универсален, чем Property Set. Последнее ограничено только ссылками на объекты. Если у вас есть это свойство в классе

Private m_oPicture          As StdPicture

Property Get Picture() As StdPicture
    Set Picture = m_oPicture
End Property

Property Set Picture(oValue As StdPicture)
    Set m_oPicture = oValue
End Property

Property Let Picture(oValue As StdPicture)
    Set m_oPicture = oValue
End Property

Вы можете позвонить Property Set Picture с

Set oObj.Picture = Me.Picture

Вы можете позвонить Property Let Picture обоими

Let oObj.Picture = Me.Picture
oObj.Picture = Me.Picture

Реализация Property Set - это то, что другие разработчики ожидают от свойств, которые являются ссылками на объекты, но иногда даже Microsoft предоставляет только Property Let для ссылочных свойств, что приводит к необычному синтаксису oObj.Object = MyObject без оператора Set. В этом случае использование оператора Set приводит к ошибке времени компиляции или выполнения, потому что Property Set Object не реализовано в классе oObj.

Я стараюсь реализовать как Property Set, так и Property Let для свойств стандартных типов - шрифтов, изображений и т. Д. - но с другой семантикой. Обычно на Property Let я обычно выполняю «глубокое копирование», то есть клонирую StdFont вместо того, чтобы просто удерживать ссылку на исходный объект.

person wqw    schedule 19.02.2011
comment
Предполагая, что у вас есть как Property Set, так и Property Let для типа объекта, и предполагая, что код реализации такой же (как в вашем примере), имеет ли VB6 какое-либо встроенное различие в том, что он на самом деле будет делать, когда разработчик вызывает любое свойство? Например, неявно ли VB6 решит внезапно передать объект по значению, а не по ссылке, если разработчик вызовет свойство Let, или есть какие-то другие мелкие нюансы, подобные этому? (Я знаю, что вы сказали, что те, которые вам нравятся, имеют отдельную семантику, но я не уверен, что язык делает что-то другое сам по себе.) - person Panzercrisis; 10.07.2017
comment
В VB6 нет опции передачи объекта по значению для params. Использование ByVal oValue As StdPicture vs ByRef oValue As StdPicture изменяет способ передачи объекта reference. Это похоже на StdPicture *oValue vs StdPicture **oValue в C / C ++ - всегда указатели, но во втором случае у вас есть возможность изменить ссылку (например, назначить ref новому объекту) внутри процедуры, и вызывающий может получить это новая ссылка. Таким образом, нет опции копирования как таковой, и я обычно использую метод Clone (например, на интерфейсе IFont) внутри Property Let, чтобы вручную внедрить семантику глубокого копирования. - person wqw; 20.07.2017
comment
Для ссылочных типов я имею в виду передачу ссылки по значению, как в VB.NET/C#. - person Panzercrisis; 20.07.2017
comment
Я принял два последних абзаца @ wqw в качестве своего личного правила кодирования, так как я читал их и нуждался в глубоких копиях коллекций и экземпляров классов; он слишком много упрощает с первого взгляда, если это всего лишь указатель или клон ... - person Marcelo Scofano Diniz; 23.08.2020

Property Set для объектно-подобных переменных (ByRef), тогда как Property Let для значений-подобных переменных (ByVal)

person Foo Bah    schedule 18.02.2011
comment
Это не проблема ByRef или ByVal, но строго используется для возврата ссылок на объекты вызывающей стороне. - person Bob77; 18.02.2011
comment
Это правда, что это не проблема ByRef / ByVal. Но он не используется для возврата ссылок на объекты вызывающей стороне. Для этого вы используете Property Get так же, как и для возврата любого другого свойства класса (не существует объектно-зависимой версии для возврата свойств класса). - person mwolfe02; 18.02.2011
comment
Да, у меня это было точно в обратном порядке, это для присвоения свойству объекта - да, действительно плохой дурак. - person Bob77; 18.02.2011