Изменить свойство класса из параметра функции, переданного по ссылке, внутри функции

#vb.net #class #pass-by-reference

#vb.net #класс #передача по ссылке

Вопрос:

Я понимаю свою проблему, но ищу рекомендуемый обходной путь.

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

 Public Class A
  Private _bFlag As Boolean

  Public Property bFlag() As Boolean
     Get
        Return _bFlag
     End Get
     Set(value As Boolean)
        _bFlag = value
        If (value) Then
           ...do something...
        End If
     End Set
  End Property

End Class
  

Когда я передаю переменную класса как ByRef локальной подпрограмме, свойство Set не запускается до завершения функции. Но у меня есть некоторые временные действия, выполняемые при переключении флага. Я хотел бы немедленно получить уведомление о переключении переменной.

 ...
Dim myClassA as New A
...
<------Here the bFlag is False
Func1(myClassA.bFlag)
<------Here the bFlag is False since Func1 completed with the bFlag set as False
<------ the Set was never called since the variable never changed at this level

Public Sub Func1(ByRef flag as Boolean)
   ... start some action
   flag = True
   ... stop some action
   flag = False
End Sub
  

Я понимаю, что это ожидаемое действие из этой ссылки, которая содержит пример:

 Sub CopyBackByRef_Explained()
    Dim v1 = New C1
    Dim vbTemp = v1.P1
    FunctionWithInt(vbTemp)
    v1.P1 = vbTemp
End Sub
  

где переменные, передаваемые по ссылке, сначала создаются временной копией для передачи в функции.

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

Комментарии:

1. How can ... get immediate notification вы имеете в виду во время выполнения кода или в среде IDE? Обычно плохой идеей является то, что установщик свойств делает что-то значимое помимо проверки. Вместо этого рассмотрим метод.

2. Есть ли причина, по которой вы должны передать его по ссылке?

3. @Plutonix код времени выполнения

4. @Steve Поскольку переменная изменялась внутри, и я хотел сохранить любые изменения даже после завершения функции

5. Когда вы передаете сложный объект, такой как класс, byval, передается указатель на исходный объект, что означает, что изменения объекта в методе влияют на исходный объект. Когда вы передаете сложный объект byref, он должен создать копию объекта для отправки обратно, когда метод завершается. Вот почему вы не запускаете свойство ‘setter’ до завершения метода. Передача вашего класса byval даст вам то, что вы хотите.

Ответ №1:

Я думаю, вы могли бы передать свойство как лямбда-выражение и использовать отражение для вызова установщика, но, вероятно, проще просто обернуть вызов установщика в лямбда-выражение и передать его:

 Func1(Sub(value) myClassA.bFlag = value)

Public Sub Func1(flag As Action(Of Boolean))
    ' start some action
    flag(True)
    ' stop some action
    flag(False)
End Sub