我在一个类中有一个字符串属性。每当修改属性值时,该属性的Setter都应该执行一些重要的外部操作。
在某些情况下,Getter本身应该在返回属性之前修改属性的值。当执行此操作时,我仍然希望执行Setter中的重要操作。
但是,每当我尝试使用属性的Getter来更改属性的值时,Setter都会被完全跳过。
下面是一些模拟代码,演示了我所看到的:
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.
啊,当然!如此简单,正是我所需要的。谢谢。