此外,ErrorsChanged理论上可以触发两次:一次是立即触发,另一次是异步验证完成后触发。这可能会产生奇怪的UI效果,因为HasErrors会在两种状态之间切换。
最后是IEnumerable GetErrors(string propertyName)方法,这个方法用于验证属性。不过,你也可以传给它一个null或空字符串来获取对象级验证错误。
它返回的是IEnumerable而不是IEnumerable<ValidationResult>,这让它看起来就像是一个C# 1的接口,而不是泛型。
不过缺乏类型安全并不是唯一的问题,这段话摘自它的文档:
此方法返回一个IEnumerable,在异步验证完成处理之前,可能会发生变化。绑定引擎因此能够在添加、删除或修改错误时自动更新用户界面验证反馈。
如果这个方法返回一个IObservable,或许就没有问题。但是在这种情况下,IEnumerable能够奏效的唯一方法是让它在等待异步验证完成之前阻塞。这样仍然会导致UI挂起。
然后是封装问题。如前所述,数据模型应该完全没有任何外部依赖。属性变化不应直接调用服务,因为这会使该类变得非常难以测试。如果你需要异步验证某些内容,请在控制器或视图模型中执行此操作。
INotifyDataErrorInfo的正确用法
尽管存在缺陷,但INotifyDataErrorInfo已经被用在很多UI框架中,所以我们无法忽略它。所幸的是,我们可以在不破坏兼容性的情况下重新定义它。










