【问题标题】:IDataErrorInfo vs ValidationRule vs ExceptionIDataErrorInfo vs ValidationRule vs 异常
【发布时间】:2010-06-05 15:03:50
【问题描述】:

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

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

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

【问题讨论】:

    标签: wpf idataerrorinfo


    【解决方案1】:

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

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

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

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

    【讨论】:

    • 今天正在阅读 IDataErrorInfo - 似乎它比 ValidationRule 更老 - 似乎 IDataErrorInfo 接口自 Framework 1.1 (msdn.microsoft.com/en-us/library/…) 以来就已经存在,但自 Framework 3.0 以来就有 ValidationRule。不要认为它会从根本上改变你的答案
    • 在我看来,ValidationRule 甚至可以在设置属性之前拦截绑定过程并执行验证。而 IDataErrorInfo 或 INotifyDataErrorInfo 需要成功设置属性(通过绑定过程)。在简单的情况下,例如验证输入的文本是数字。在这种情况下,我找不到 IDataErrorInfo 和 INotifyDataErrorInfo 工作的任何方法,因为如果输入的文本不是数字(可转换为某些模型中的数字类型),所以看起来只有 ValidationRule 有效
    • @Hopeless 使用ValidationRule时,如果属性是从代码(视图模型)而不是UI以编程方式设置的,它也会拦截绑定过程?
    【解决方案2】:

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

    IDataErrorInfo

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

    验证规则

    • 在单独的类中维护验证规则
    • 提高可重用性。例如,您可以实现必填字段 验证类在整个应用程序中重复使用它。

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

    【讨论】:

      【解决方案3】:

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

      验证规则

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

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

      IDataErrorInfoINotifyDataErrorInfo

      • 这会将验证放入视图模型中,适用于允许在视图模型中存储非法值的场景。可以通过这个界面向用户提供具体的错误信息。

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

      • 重复使用验证规则不太方便,但无论如何也不是不可能的。您只需要实现自己的辅助方法或对象即可根据需要执行验证。

      例外情况

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

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-01-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多