我应该在从程序代码调用Execute之前检查ICommand的CanExecute方法吗?

Mat*_*hew 8 .net c# wpf routed-commands icommand

ICommand在XAML中使用s时,WPF使用该CanExecute方法启用或禁用与该命令关联的控件.但是如果我Execute从程序代码中调用呢?我应该首先检查CanExecute以确保该命令可以执行,还是应该Execute为我处理此检查?

换句话说,我应该这样做:

if (someCommand.CanExecute(parameter, target))
    someCommand.Execute(parameter, target);
Run Code Online (Sandbox Code Playgroud)

或者就是这样:

someCommand.Execute(parameter, target);
Run Code Online (Sandbox Code Playgroud)

the*_*tro 8

好的风格会决定你应该做前者,先检查CanExecute.这将强制执行适当的分解和实施的一致性.此外,如果您确实想要使用绑定到按钮的此命令,它将按预期工作.

  • 从合同上看,这感觉“合适”。我还要补充一点,如果要检查的条件无论如何都依赖于命令的外部状态(并因此可以由其他线程修改,等等),则需要锁定CanExecute / Execute序列。 (2认同)

Stu*_*lar 5

您应该只调用Execute并让命令实现处理验证。CanExecute主要为UI状态绑定提供。

除了非常简单的单线程方案外,即使您先调用CanExecute,也很容易出现争用情况,由此命令有效性在CanExecute和Execute调用之间改变,从而使对CanExecute的调用变得毫无意义。

  • 正如您刚刚指出的那样,它们不一定按顺序执行,即使执行了,要阻止另一个线程在这两个顺序调用之间更改命令的基础数据或状态,是什么?而命令实现知道它正在运行的上下文,并且可以根据需要自动同步对共享数据的访问。最好也可以确定命令在执行时是否有效。 (2认同)
  • 如果对数据的访问已同步,则数据“不能”更改。我的观点是,只有命令实现才能知道这是否必要。而且,没有“容易出现竞争条件的利基市场”之类的东西:要么存在对数据的并发访问,在这种情况下就需要保护它,或者没有。您似乎在争辩说,由于这种类型的竞赛条件很少发生,因此可以忽略它们。这是一种危险的态度-如果有数百万的用户在运行该程序,则发生问题的可能性趋于不可避免。 (2认同)