【问题标题】:Why should INotifyPropertyChanged and plain events be mutually exclusive?为什么 INotifyPropertyChanged 和普通事件应该是互斥的?
【发布时间】:2013-09-16 18:55:51
【问题描述】:

MS 推荐

INotifyPropertyChanged Interface on MSDN 状态:

在绑定客户端之间的绑定中发生更改通知 和一个数据源,你的绑定类型应该是:

  • 实现 INotifyPropertyChanged 接口(首选)。

  • 为绑定类型的每个属性提供一个更改事件。

不要两者都做。

问题围绕着为什么“不要两者都做”。

上下文

我正在编写一个运行服务器端的程序。一堆类打算在本地使用,并作为使用 WCF 的 HTTP 客户端请求的答案发送(不通知客户端)。为此,它们是从 XML 模式生成的(例如在预构建事件中:"$(TargetFrameworkSDKToolsDirectory)xsd.exe" "$(ProjectDir)generated\SystemState.xsd" /classes /enableDataBinding /namespace:XXX /o:"$(ProjectDir)generated"

/enableDataBinding 选项可以方便地进行自动通知(所有通知接收器都是服务器端的)。

这对于某些通知接收器来说确实很好(服务器状态更改触发了一些相关代码)。那些甚至对细节都不感兴趣,只是想知道一个属性更改,这非常适合 INotifyPropertyChanged。

但有些接收者对某个特定的属性更改特别感兴趣,这非常适合“普通”MyFooChanged 事件。

选择

我有两个选择:

  • 编写接收通用 PropertyChanged 事件的接收器代码,根据类型为字符串的属性名称进行过滤...感觉就像 Code smell(容易出错,缺少编译时检查等)。

  • 最好为接收者使用通用PropertyChanged事件,为某些特定接收者感兴趣的少数属性写一两个“普通”事件MyFooChanged in. 所有事件接收器都将保持简单和干净。

第二个看起来更干净,但违反了 Microsoft 的建议。

MS 的推荐在这里有用吗?

在这种情况下,我真的应该担心微软说“不要两者都做”吗?下面以幽默的方式向 XKCD 致敬,以陈述问题的精神:

我认为现在没有问题,但讨论微软声明不同时做这两件事的原因可能会很有趣。

  • 在什么情况下两者都做不好? Windows 窗体? WPF ?
  • 如果两者都做会怎样?某些控件中的重复更新? (从 .NET 1.1 及更高版本的早期开始,大多数 MS 课程都对此进行了检查。)
  • 还有什么?

干杯,

【问题讨论】:

  • INotifyPropertyChanged 可以使用表达式进行强类型化(不基于魔术字符串)。尽管如此,MSDN 文档仍在讨论 DataBinding,这正是 INotifyPropertyChanged 真正重要的地方。我不明白为什么服务器端代码必须有任何这种限制。顺便说一句,我不明白为什么服务器端代码应该基于事件......
  • 互斥不是我用来描述微软声明的术语。一个不会先发制人地排除另一个。
  • @Blam:MS 写了“不要两者都做”,这不是和“互斥”的意思一样吗?
  • 有一个替代方案,也许并非适用于所有情况,但对于某些人来说绝对是有趣的,如果只是为了更清洁地解决线程问题。该解决方案是:忘记这两个选项,而是使用 Reactive Extensions 实现观察者。或者,正如一项扩展研究显示的那样,也许确实实现了传统事件,但通过Observer.FromEventPattern 等方式使用它们。最佳解决方案取决于用例。
  • 什么?查找“互斥”。

标签: c# .net wpf winforms wcf


【解决方案1】:

在什么情况下两者都做不好? Windows 窗体? WPF ?

两者都支持INotifyPropertyChangedPropertyNameChanged 基于事件的通知,因此它在您进行数据绑定时普遍适用。

如果你两者都做会发生什么?某些控件中的重复更新?

要回答这个问题并不容易(要获得明确的答案,需要的不仅仅是阅读相关资料)。显然会有很多不必要的重复工作。在像这个这样的只读场景中,我不会完全期待烟花。

还有什么?

我认为的主要问题是缺乏一致性,这会导致误解,从而导致代码错误。

如果没有特殊因素强烈建议不这样做,我会选择INotifyPropertyChanged,因为它是众所周知的,可以立即理解并且在事件处理程序上更轻松。您也可以use expression trees 使其成为强类型。

【讨论】:

  • 感谢您提及表达式树以恢复强输入。
猜你喜欢
  • 2021-11-21
  • 1970-01-01
  • 2012-07-21
  • 2017-03-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-02
相关资源
最近更新 更多