Защита от повторного входа и инвариантных нарушений при использовании INotifyPropertyChanged? - PullRequest
0 голосов
/ 17 апреля 2020

При использовании INotifyPropertyChanged существует риск ошибок повторного входа, поскольку обработчик события PropertyChanged может вызвать метод отправителя прямо или косвенно. Поскольку типичная реализация вызывает эти события, как только свойство назначено, это скрытый источник точек повторного входа во всех методах. Каждый раз, когда свойство присваивается, нужно будет защититься от повторного входа.

Кроме того, событие PropertyChanged может выставить объект, когда он находится в состоянии, которое нарушает один из его инвариантов класса. Например, инвариант класса утверждает, что если и только свойство A имеет значение true, то свойство B будет ненулевым. Наивный код для присвоения A, тогда B вызовет событие свойства изменено, если только один из них изменился Затем обработчик событий будет наблюдать объект в этом состоянии, когда инвариант класса был нарушен, но еще не восстановлен.

Эти проблемы менее важны при реализации INotifyPropertyChanged в моделях представления. Обновление пользовательского интерфейса вряд ли будет включать код, который может вызвать эти проблемы. Однако многие люди реализуют его и на моделях, потому что это значительно упрощает обновление пользовательского интерфейса. Там, кажется, больше беспокойства. Я вижу очень мало обсуждения этих вопросов в Интернете, даже когда я ищу их. (Я нашел INotifyPropertyChanged и последовательность - когда поднять PropertyChanged? )

Мой вопрос состоит из двух частей:

  1. При реализации INotifyPropertyChanged в объекты модели , должен ли я защищаться от проблем повторного входа и нарушения ограничений? Почему или почему нет?
  2. Существует ли простой способ, без шаблонного, защитить от повторного входа и нарушений нарушения? (Я видел предложения отложить повышение событий изменения, но, похоже, для этого нужно либо всегда явно / вручную вызывать события изменения в конце метода, который может быть подвержен ошибкам, либо использовать каркас и обернуть каждое тело метода в оператор using, который задерживает события изменения внутри оператора using.)
...