23

谁能告诉我在 WPF 中哪个是更好的验证方法。

  1. 实现 IDataErrorInfo
  2. 创建验证规则
  3. 抛出异常

在性能、内存泄漏、代码可维护性和重用方面。

4

3 回答 3

28

这是一个复杂的请求,老实说,它可能会因偏好而有所不同。但是,这是我的理解:

  • 性能:除非您的其他实现非常可怕,否则几乎每次都会丢失异常。抛出/捕获循环有很大的开销。(轶事:我有一个“必须是数字”检查,这是一个例外,它在失败时“滞后”了 UI 一段明显的时间,但是当转换为 ValidationRule 时,它​​实际上是即时的。)
  • 内存泄漏:这取决于您的验证规则或 IDataErrorInfo 实现是如何完成的。
  • 代码可维护性、重用性:当然,这是有趣的部分。您真正应该问的是“什么时候适合使用 ValidationRule 而不是 IDataErrorInfo,反之亦然?”

ValidationRules 比 IDataErrorInfo 更早(我相信后者是在 .Net 3.5 中引入的)。仅基于这一点,WPF 团队似乎更喜欢 IDataErrorInfo。但事实是它们是为不同的事物而建造的。如果您有 MVVM 或等效模式,则 IDataErrorInfo 更适合模型中的错误(例如,负年龄),而 ValidationRules 更适合视图中的错误(例如,☃ 年龄)。当然可以让 ValidationRules 执行“业务逻辑”检查,或者让 IDataErrorInfo 告诉您“unicode 雪人不是有效年龄”,但是通过保持这种模式,您(可能)会获得最佳的可维护性。

但是不要在初始测试之外使用异常进行验证,以查看您应该测试的确切条件。

于 2010-06-06T00:27:13.043 回答
8

使用异常进行错误处理并不是一个好主意。使用异常会降低性能。这是选择和实施 IDataErrorInfo 或创建 ValidationRule 的问题。

IDataErrorInfo

  • 验证逻辑保留在视图模型中,易于实现和维护
  • 完全控制视图模型中的所有字段

验证规则

  • 在单独的类中维护验证规则
  • 增加可重用性。例如,您可以实现所需的字段验证类在整个应用程序中重用它。

我的观点是,对于像必填字段验证、电子邮件地址验证等常见验证,您可以使用验证规则。如果您需要进行自定义验证,例如范围验证,或者任何自定义验证,请使用 IDataerrorinfo。

于 2013-09-30T03:42:28.877 回答
7

与其他两个答案中提出的观点相比,我对该主题的看法略有不同:

验证规则

  • 这适用于需要在更新绑定源之前完成的验证。您可能希望这样做的原因包括能够向用户显示特定的错误消息,尤其是与数据转换之前的值相关的消息,或验证必须转换的数据。

  • 正如其他答案中所述,在多个控件之间共享验证也更容易一些,因为您可以执行诸如创建ValidationRule用于多个绑定的单个控件之类的操作,或者使用 aBindingGroup提供一次ValidationRule检查多个绑定的单个控件。

IDataErrorInfoINotifyDataErrorInfo

  • 这将验证放入视图模型中,并且适用于允许在视图模型中存储非法值的场景。可以通过该接口向用户提供特定的错误消息。

  • 验证可用于视图模型实现的任何客户端,从而为此类验证提供更好的重用。

  • 验证规则的重用不太方便,但无论如何都不是不可能的。你只需要实现你自己的辅助方法或对象来执行你喜欢的验证。

例外

  • 基于性能问题,其他答案避开了验证例外。但是,根据我的经验,UI 场景中的异常处理通常很好。尽管异常处理有额外的开销,但它的发生速度仍然比用户能够注意到的要快(尽管有未经证实的“轶事”)。

  • 异常的一个重要方面是它为您提供了在视图模型上实现错误通知接口的许多好处,同时仍然防止在视图模型属性上设置无效值。换句话说,您可能会ValidationRule遇到发生得太早和IDataErrorInfo太晚的验证场景。从属性设置器中抛出异常将解决这些情况。

底线:每种验证技术都有其优点和缺点,并且适用于特定场景。没有一个是一致优于其他任何一个。这在很大程度上取决于您尝试执行哪种验证,以及您希望在哪里看到执行该逻辑。

于 2020-04-20T06:04:01.063 回答