Sub Main() Dim att As New Attribute ' The following line should "do important stuff" ' (and it does). att.Value = "FOO" ' The following line sould add "BAR" to the end and "do important stuff" ' (it does neither). Dim getValue As String = att.Value MsgBox("Value: " & getValue) End Sub Class Attribute Private _value As String = "" Public Property Value As String Get ' Modify value using Setter. Value = _value & "BAR" ' Return value. Return _value End Get Set(setVal As String) ' Do important stuff. MsgBox("Doing important stuff!") '... ' Set value. _value = setVal End Set End Property End Class
When I run debugging with a breakpoint on the "Get" line, you can see that the
Value = _value & "BAR" line does NOT cause the setter to execute. Instead, it just modifies the value of the Value variable in memory, rather than actually executing the Setter.
Is this by design? If so, any explanation as to why?
Can I tweak my code or change a setting somewhere to make my Setter be executed when called from the Getter?
PS, I'm aware I could write a separate function for setting the value and call that from both the Getter and the Setter. My reason for posting is because I want to avoid that extra overhead if possible.
EDIT 7/3/2019 @ 8:50 AM This is similar to this question. The accepted answer on that post does answer the question of "is this by design and why?", but I'm not sure I understand it. Some additional explanation would be appreciated.
In addition, none of the answers on that post answer the second part of my question, "Can I tweak my code to somehow call the Setter from within the Getter?" This was my main reason for posting a new question.
EDIT 7/3/2019 @ 9:10 AM I'm adding someting closer to my real class below to demonstrate why I'm doing it like this:
(Note: the Attribute object is a class of object that belongs to the software that I'm writing this add-in for. It's impossible for me to modify or inherit it. So instead I'm writing a "Definition" class that "extends" it with additional functionality.)
Class AttributeDefinition Public AttributeName As String Private AttributeSet As Inventor.AttributeSet Sub New(AttributeName As String, AttributeSet As Inventor.AttributeSet) Me.AttributeName = AttributeName Me.AttributeSet = AttributeSet If AttributeSet.NameIsUsed(AttributeName) Then AttributeObject = AttributeSet.Item(AttributeName) End If End Sub Private AttributeObject As Inventor.Attribute Property Value() As String Get If AttributeObject Is Nothing Then Value = "" End If Return AttributeObject.Value End Get Set(setVal As String) If AttributeObject Is Nothing Then ' Create Attribute with empty string as value. ' (In actuality, this taks much more than just one line of code). AttributeObject = AttributeSet.Add(AttributeName, Inventor.ValueTypeEnum.kStringType, setVal) Else AttributeObject.Value = setVal End If End Set End Property End Class
In short, the Getter checks if the Attribute actually exists before trying to return its value. If it doesn't, it calls the Setter to create it.
The Setter is fully responsible for setting the Attribute's value, including creating it with the specified value if it doesn't exist. This is actually very involved (more than one line of code), so I don't want to duplicate it in another method. I also don't want to create a separate dedicated method for it, unless calling the Setter from the Getter is impossible.