Вызов 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, для автоматического создания события.

В качестве общего примечания, не забудьте утилизировать свои подписки, если вы также предлагаете способ удаления или очистки элементов. Я вижу, что в вашем примере вы отбрасываете возвращенную подписку.

Другие вопросы по тегам