MVVM:我应该从我的Execute方法中检查我的“CanExecute”方法吗?
问题描述:
我了解使用的CanExecute()
和Execute()
,但我想了解一下下面的场景:MVVM:我应该从我的Execute方法中检查我的“CanExecute”方法吗?
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。这可能有点主观,但我希望有一个“标准”的方式来做到这一点。
难道我们:
- 防止可能的NullReferenceException通过做
if (MyBar != null)
第一? - 通过验证
CanDoFoo()
是否返回true来防止可能的NullReferenceException? - 假设消费视图行为正常,并且已经验证它可以调用
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()
来验证业务逻辑,或者假设消费视图正在运行? (请记住,这只会打破业务逻辑)。
基本上归结为这个......我们是否采取了预防措施以确保消费者的视线不会因为行为不当而在脚下自己拍摄?
答
任何执行命令调用WPF或Silverlight将做到这一点的,所以你不必从UI系统的担心......
但它是一个公共方法。检查null是你能做的最快速的事情之一。它没有伤害,并且它更安全,因为您将抛出一个没有guard子句的空异常。
从语义上讲,CanExecute
可能会执行不同于空检查,所以我只是在Execute
方法做空检查,不一定检查CanExecute
。
我也会补充说,检查null应该是一个常见的防御性编码技术。如果你确实需要一个null的异常,那么检查一下你自己并明确地处理异常。这使您可以更好地控制异常,这样可以使它们对应用程序更有意义。 – SRM 2011-05-12 20:52:03
我扩大了我的问题了一下。我可以理解防止应用程序异常的必要性,但是如何让我们的ViewModel不会因业务逻辑而崩溃? – 2011-05-12 20:55:26
检查没有伤害。但更好的问题是:当'Execute'被调用但是'CanExecute'为false时,你想要做什么?你想默默地失败吗?或者你想做些事情来处理这种情况?确定这一点取决于您的业务逻辑。 – 2011-05-12 21:26:49