从Getter内调用属性Setter不会执行Setter吗?

时间:2019-07-03 13:21:19

标签: .net vb.net properties

我在一个类中有一个字符串属性。每当修改属性值时,该属性的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。

这是设计使然吗?如果是这样,对原因有什么解释?

我可以调整代码或在某个地方更改设置以使从Getter调用我的Setter吗?


PS,我知道我可以编写一个单独的函数来设置值,然后从Getter和Setter调用它。我之所以发布,是因为我想尽可能避免这种额外的开销。


EDIT 7/3/2019 @ 8:50 这类似于this question。该职位上公认的答案确实回答了“这是设计使然,为什么吗?”的问题,但我不确定我是否理解。一些其他的解释将不胜感激。

此外,该帖子的所有答案都无法回答我问题的第二部分:“我可以调整代码以某种方式从Getter内调用Setter吗?”这是我发布新问题的主要原因。


EDIT 7/3/2019 @ 9:10 我在下面的我的真实课堂上添加了一些东西,以说明为什么我要这样做:

  

(注意:Attribute对象是属于该类的对象,属于我正在为其编写插件的软件。对我来说,修改或继承它是不可能的。因此,我正在编写“ Definition”类,以通过其他功能“扩展”它。)

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会检查Attribute是否确实存在。如果没有,它将调用Setter来创建它。

设置器完全负责设置属性的值,包括使用指定值创建(如果不存在)。这实际上非常复杂(不止一行代码),所以我不想在另一种方法中重复它。我也不想为其创建单独的专用方法,除非无法从Getter调用Setter。

2 个答案:

答案 0 :(得分:1)

只需在分配Value之前添加Me.,它将调用设置器

Public Property Value As String
    Get
        ' Modify value using Setter.
        Me.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

enter image description here

答案 1 :(得分:0)

我同意jmc的评论,这很糟糕。话虽如此,这应该可以解决您的问题。 类属性     私有_value As String =“”

Public Property Value As String
    Get
        Return Me._value & "BAR"
    End Get
    Set(setVal As String)
        ' Do important stuff.
        MsgBox("Doing important stuff!") 'what???????
        ' Set value.
        Me._value = setVal
    End Set
End Property

结束班级

我添加了我。进行一些澄清。