Вызов свойства Setter изнутри Getter не выполняет Setter? - PullRequest
0 голосов
/ 03 июля 2019

У меня есть строковое свойство в классе. Установщик свойства должен выполнять некоторые важные внешние операции всякий раз, когда изменяется значение свойства.

В некоторых случаях сам получатель должен изменить значение свойства перед его возвратом. Когда он это сделает, я все еще хочу, чтобы важные операции в 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" НЕ вызывает выполнение установщика. Вместо этого он просто изменяет значение переменной Value в памяти, а не фактически выполняет Setter.

Это задумано? Если да, то какое-нибудь объяснение почему?

Могу ли я настроить свой код или изменить настройку где-нибудь, чтобы мой Setter выполнялся при вызове из Getter?


PS, я знаю, что мог бы написать отдельную функцию для установки значения и вызвать его как из Getter, так и из Setter. Моя причина публикации состоит в том, что я хочу избежать этих дополнительных затрат, если это возможно.


РЕДАКТИРОВАНИЕ 7/3/2019 @ 8:50 AM Это похоже на этот вопрос . Принятый ответ на этот пост действительно отвечает на вопрос «это по замыслу и почему?», Но я не уверен, что понимаю это. Некоторое дополнительное объяснение будет оценено.

Кроме того, ни один из ответов в этом посте не отвечает на вторую часть моего вопроса: «Могу ли я настроить свой код, чтобы каким-то образом вызвать Setter изнутри Getter?» Это было моей главной причиной для публикации нового вопроса.


РЕДАКТИРОВАНИЕ 7/3/2019 @ 9:10 AM Я добавляю кое-что ближе к моему настоящему классу ниже, чтобы продемонстрировать, почему я делаю это так:

(Примечание. Объект 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 из Getter невозможен.

Ответы [ 2 ]

1 голос
/ 03 июля 2019

Просто добавьте 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

0 голосов
/ 03 июля 2019

Я согласен с комментарием jmc, это плохо.Сказав, что это должно исправить вашу проблему.Атрибут класса Private _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

Конечный класс

Я добавил Me.уточнить несколько.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...