【发布时间】:2019-07-03 13:21:19
【问题描述】:
我在一个类中有一个字符串属性。每当修改属性的值时,该属性的 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
当我在“Get”行使用断点运行调试时,您可以看到Value = _value & "BAR" 行不会导致setter 执行。相反,它只是修改内存中 Value 变量的值,而不是实际执行 Setter。
这是设计使然吗?如果有,有什么解释吗?
我可以调整我的代码或更改某处的设置以使我的 Setter 在从 Getter 调用时被执行吗?
PS,我知道我可以编写一个单独的函数来设置值并从 Getter 和 Setter 调用它。我发帖的原因是因为我想尽可能避免额外的开销。
编辑 2019 年 7 月 3 日 @ 上午 8:50 这类似于this question。该帖子上接受的答案确实回答了“这是设计使然,为什么?”的问题,但我不确定我是否理解。一些额外的解释将不胜感激。
此外,该帖子中的任何答案都没有回答我的问题的第二部分,“我可以调整我的代码以某种方式从 Getter 中调用 Setter 吗?”这是我发布新问题的主要原因。
编辑 2019 年 7 月 3 日 @ 上午 9:10 我在下面添加了一些更接近我的真实课程的内容,以说明我为什么这样做:
(注意:Attribute 对象是属于我正在为其编写此插件的软件的一类对象。我无法修改或继承它。因此,我正在编写“定义”用附加功能“扩展”它的类。)
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
简而言之,Getter 在尝试返回其值之前检查属性是否确实存在。如果没有,它会调用 Setter 来创建它。
Setter 完全负责设置 Attribute 的值,包括在不存在时使用指定值创建它。这实际上是非常复杂的(不止一行代码),所以我不想在另一种方法中复制它。我也不想为它创建一个单独的专用方法,除非从 Getter 调用 Setter 是不可能的。
【问题讨论】:
-
那是一些设计糟糕的代码。那不应该是一个属性。
-
@jmcilhinney 你介意解释一下原因并建议我应该怎么做吗?
-
@AFriend,我看到了那个。起初,我不明白接受的答案是如何设计的。重读后,我想我有点明白了。但是,没有一个答案能回答我问题的第二部分,“我可以调整我的代码或更改某处的设置以使我的 Setter 在从 Getter 调用时被执行吗?”
-
“通过直接分配 _avg 字段来解决您的问题”在您的情况下,它将是
_value
标签: .net vb.net properties