MVVM:我应该检查我的“CanExecute”吗?我的执行方法中的方法?
我了解 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。这可能有点主观,但我希望有一种“标准”的方法。
我们是否:
- 首先执行
if (MyBar != null)
来防止可能出现的 NullReferenceException? - 通过验证
CanDoFoo()
返回 true 来防止可能的 NullReferenceException? - 假设消费视图行为正常并且已经验证它可以调用
DoFoo()
方法?
As a side note, the primary reason I asked this is because when I was writing unit tests I realized that someone could break my ViewModel by calling
Execute()
methods without calling their CanExecute()
counterparts? Obviously in my unit tests I check to see that I can execute the method before doing so, but consuming views might decide to ignore that.Update: (Scenario 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() 再次验证业务逻辑还是假设消费视图正在运行? (请记住,这只会破坏业务逻辑)。
基本上可以归结为……我们是否采取预防措施来确保消费视图不会因为行为不当而搬起石头砸自己的脚?
I understand the use of CanExecute()
and Execute()
, but I'm wondering about the following scenario:
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
}
}
Basically, a consuming view could decide to call directly into the DoFoo method (obviously breaking the point of the ICommand
interface) and cause a NullReferenceException. This may be a bit subjective, but I'm hoping for a "standard" way of doing it.
Do we:
- Prevent the possible NullReferenceException by doing a
if (MyBar != null)
first? - Prevent the possible NullReferenceException by verifying that
CanDoFoo()
returns true? - Assume that the consuming view is behaving properly and has already verified that it can call into the
DoFoo()
method?
As a side note, the primary reason I asked this is because when I was writing unit tests I realized that someone could break my ViewModel by calling
Execute()
methods without calling their CanExecute()
counterparts? Obviously in my unit tests I check to see that I can execute the method before doing so, but consuming views might decide to ignore that.Update: (Scenario 2)
As an expansion to this question, I also want to add in the scenario where the DoFoo()
method does not break in terms of exceptions, but could break logically?
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);
}
}
This second scenario does not actually break (the command can process fine), however, it breaks down logically. So, do we validate the business logic a second time by calling CanDoFoo()
or assume the consuming view is behaving? (Remember, this only breaks the business logic).
Basically it boils down to this... Do we put in preventive measures to ensure the consuming view is not shooting itself in the foot by misbehaving?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
WPF 或 Silverlight 中命令调用的任何实现都会执行此操作,因此您不必从 UI 系统担心它......
但它是一个公共方法。检查 null 是您可以做的最快的事情之一。它不会造成伤害,而且更安全,因为如果没有保护子句,您将抛出空异常。
从语义上讲,
CanExecute
的实现方式可能与 null 检查不同,因此我只在Execute
方法中执行 null 检查,而不一定检查CanExecute
。Any implementation of command calling in WPF or Silverlight will do this, so you don't have to worry about it from the UI system...
But it is a public method. Checking for null is one of the fastest things you can do. It doesn't hurt and it is much more safe since you will throw a null exception without the guard clause.
Semantically,
CanExecute
may be implemented differently than a null check, so I would just do the null check in theExecute
method, not necessarily checkCanExecute
.