【问题标题】:MVVM: Should I check my "CanExecute" method from within my Execute methods?MVVM:我应该从我的 Execute 方法中检查我的“CanExecute”方法吗?
【发布时间】:2011-05-12 20:34:20
【问题描述】:

我了解CanExecute() 和Execute() 的用法,但我想知道以下情况:

public class MyViewModel : NotificationObject
{
    public MyViewModel()
    {
        FooCommand = new DelegateCommand(DoFoo, CanDoFoo);
    }

    public Bar MyBar { get; set; }

    public DelegateCommand FooCommand { get; private set; }

    public Boolean CanDoFoo()
    {
        return (MyBar != null)
    }

    public void DoFoo()
    {
        MyBar.BarFunc(); //Potential for a NullReferenceException
    }
}

基本上,消费视图可以决定直接调用 DoFoo 方法(显然打破了ICommand 接口的要点)并导致 NullReferenceException。这可能有点主观,但我希望有一种“标准”的方式来做这件事。

我们:

  1. 通过先执行if (MyBar != null) 来防止可能的 NullReferenceException?
  2. 通过验证CanDoFoo()是否返回true来防止可能的NullReferenceException?
  3. 假设消费视图行为正常并且已经验证它可以调用DoFoo() 方法?


作为旁注,我问这个的主要原因是因为当我编写单元测试时,我意识到有人可以通过调用 Execute() 方法而不调用他们的 CanExecute() 同行来破坏我的 ViewModel?显然,在我的单元测试中,我会检查我是否可以在执行该方法之前执行该方法,但使用视图可能会决定忽略它。


更新:(场景 2)

作为对这个问题的扩展,我还想补充一下DoFoo() 方法在异常方面没有中断,但可以在逻辑上中断的场景?

public class MyViewModel : NotificationObject
{
    public MyViewModel()
    {
        FooCommand = new DelegateCommand(DoFoo, CanDoFoo);
    }

    public Int32 Age { get; set; }

    public DelegateCommand FooCommand { get; private set; }

    public Boolean CanDoFoo()
    {
        return (Age >= 21)
    }

    public void DoFoo()
    {
        ProvideAlcohal(Age);
    }
}

第二种情况实际上并没有中断(命令可以正常处理),但是,它在逻辑上崩溃了。那么,我们是通过调用CanDoFoo() 再次验证业务逻辑还是假设消费视图正在运行? (请记住,这只会破坏业务逻辑)。

基本上归结为...我们是否采取了预防措施来确保消费视图不会因行为不端而自取其辱?

【问题讨论】:

    标签: c# mvvm exception-handling prism icommand


    【解决方案1】:

    在 WPF 或 Silverlight 中的任何命令调用实现都会执行此操作,因此您不必担心 UI 系统中的问题...

    但它是一种公共方法。检查 null 是您可以做的最快的事情之一。它不会受到伤害,而且更安全,因为您将在没有保护子句的情况下引发空异常。

    从语义上讲,CanExecute 的实现方式可能与空检查不同,所以我只会在 Execute 方法中进行空检查,不一定要检查 CanExecute。

    【讨论】:

    • 我还要补充一点,无论如何检查 null 应该是一种常见的防御性编码技术。如果您真的想要 null 上的异常,请自行检查并明确处理异常。这使您可以更好地控制异常,从而使它们对您的应用程序更有意义。
    • 我稍微扩展了我的问题。我可以理解防止应用程序异常的必要性,但是如何防止我们的 ViewModel 破坏其业务逻辑呢?
    • 检查一下也无妨。但更好的问题是:当Execute 被调用但CanExecute 为假时,你想做什么?你想默默地失败吗?或者你想做点什么来处理那个案子?这取决于您的业务逻辑来确定。
    • 嗯,我想这和我想的一样……这在不同的人之间是主观的。我希望几个月前我在浏览 MVVM 模式时错过了一些标准指南。
    • 是的,我认为您不再真正关注 MVVM,而只是关注您的业务逻辑。
    猜你喜欢
    • 2011-10-20
    • 2011-10-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多