MVVM:我应该检查我的“CanExecute”吗?我的执行方法中的方法?

发布于 2024-11-06 20:54:55 字数 1957 浏览 1 评论 0原文

我了解 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() 方法?


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:

  1. Prevent the possible NullReferenceException by doing a if (MyBar != null) first?
  2. Prevent the possible NullReferenceException by verifying that CanDoFoo() returns true?
  3. 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

晚雾 2024-11-13 20:54:55

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 the Execute method, not necessarily check CanExecute.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文