Вызов OnNext при изменении свойства
Я думаю, что я плотный здесь. У меня есть два класса, один из которых содержит список другого - вот урезанная версия:
Class Service
Private _ratesList As New List(Of Rate)
Public Property Rates As IEnumerable(Of Rate)
Public Sub AddRate(rate As Rate)
_ratesList.Add(rate)
End Sub
End Class
Class Rate
Private _priority As Integer
Public Property Priority As Integer
Get
Return _priority
End Get
Set(ByVal Value As Integer)
_priority = Value
End Set
End Property
End Class
Мне нужно, чтобы родительский объект Service был уведомлен всякий раз, когда один из объектов Rate в его списке изменил свой приоритет. Следующее делает то, что я хочу:
Class Service
Private _ratesList As New List(Of Rate)
Public Property Rates As IEnumerable(Of Rate)
Public Sub AddRate(rate As Rate)
rate.PriorityChanges.Subscribe(AddressOf HandleRatePriorityChange)
_ratesList.Add(rate)
End Sub
Private Sub HandleRatePriorityChange(rate As Rate)
' Do something
End Sub
End Class
Class Rate
Private _priorityChanges As New Subject(Of Rate)
Public ReadOnly Property PriorityChanges As IObservable(Of Rate)
Get
Return _priorityChanges
End Get
End Property
Private _priority As Integer
Public Property Priority As Integer
Get
Return _priority
End Get
Set(ByVal Value As Integer)
_priority = Value
_priorityChanges.OnNext(Me)
End Set
End Property
End Class
Таким образом, класс тарифов вызывает OnNext каждый раз, когда для свойства устанавливается новое значение.
Меня беспокоит то, что я использую тему вместо (например) Observable.Create. Какой рекомендуемый способ сделать это? Я уверен, что это ослепительно очевидно, но я дошел до состояния, когда не вижу дерева для деревьев!
2 ответа
Спасибо Дэйву Секстону за его очень информативный пост в блоге " Использовать тему" или "Не использовать тему". Ответ в том, что мои опасения по поводу использования Subject были неуместны в этих конкретных обстоятельствах, но, пожалуйста, прочитайте блог для получения дополнительной информации
В вашем случае с помощью BehaviorSubject
возможно, самый простой дизайн для достижения вашей цели (как это было предложено Брэндоном). В этом случае это выглядит как победитель.
В более широком представлении дизайна или архитектуры вы можете рассмотреть существующие шаблоны событий для распространения уведомлений об изменениях. INotifyPropertyChanged
интерфейс и ObservableCollection(Of T)
предоставить события, чтобы выставить уведомление об изменениях. Они очень популярны в WPF, однако существуют в BCL, поэтому их можно использовать в приложениях, не относящихся к wpf.
Если вы решили принять их, вы можете перейти к Rx с помощью фабрик FromEvent, которые большинство людей переносят в пользовательский метод расширения. В приведенном выше простом примере это будет намного больше кода без реальной выгоды. В более широкой кодовой базе это может быть полезно, особенно если вы работаете в WPF или используете ткача, такого как Fody, для автоматического создания события.
В качестве общего примечания, не забудьте утилизировать свои подписки, если вы также предлагаете способ удаления или очистки элементов. Я вижу, что в вашем примере вы отбрасываете возвращенную подписку.