1

我了解 and 的使用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()或假设消费视图正在运行来再次验证业务逻辑?(请记住,这只会破坏业务逻辑)。

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

4

1 回答 1

5

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

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

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

于 2011-05-12T20:42:18.770 回答