为什么RelayCommands通常使用延迟初始化?

Wil*_*lka 13 c# data-binding xaml mvvm lazy-initialization

当使用Josh Smith的RelayCommand时,我见过的大多数例子都使用延迟初始化,例如:

public class ViewModel
{
    private ICommand myCommand;

    public ICommand MyCommand
    {
        get
        {
            if (myCommand == null)
            {
                myCommand = new RelayCommand(p => DoSomething() );
            }

            return myCommand;
        }
    }
    // ... stuff ...

}
Run Code Online (Sandbox Code Playgroud)

而不是在构造函数中创建RelayCommand,如下所示:

public class ViewModel
{
    public ViewModel()
    {
            MyCommand = new RelayCommand(p => DoSomething());
    }

    public ICommand MyCommand
    {
        get;
        private set;

    }

    // ... stuff ...
}
Run Code Online (Sandbox Code Playgroud)

在这里使用延迟初始化有什么好处?在设置绑定时必须调用get属性,所以我看不出在构造函数中使用此方法而不是设置的原因.

我在这里错过了什么吗?

Jud*_*ngo 15

实际上,WPF和Silverlight每次绑定只会获得一次relay命令,因此您根本不需要存储支持字段:

public ICommand MyCommand
{
    get
    {
        return new RelayCommand(p => DoSomething());
    }
}
Run Code Online (Sandbox Code Playgroud)

因此,虽然按照你的建议在.ctor中创建它没有任何问题,但是没有什么理由可以.

  • @Peter Duniho:不仅是微软; 我的视图模型一直直接从它自己的方法调用它的命令(和CanExecute()).所以,不,每次创建一个新实例都是不明智的. (3认同)
  • _"WPF和Silverlight每次绑定只会获得一次relay命令"_ - 我知道在实践中这是真的.但是,鉴于文档没有_promise_这种行为,每次检索属性值时创建新对象真的是那么明智吗?那天微软无论出于什么原因决定让你的模型对象保持命令对象引用而不是在某个地方缓存它更有意义,它们只是在每次需要时从属性中获取值? (2认同)
  • @Peter Duniho:所以我意识到为什么我没有使用字段/属性初始值设定项 - 因为我的命令本身也调用视图模型实例方法。当然,我可以将这些初始化移动到构造函数中,尽管我不确定它会产生很大的不同。我选择根本不重构。 (2认同)
  • 这是一个可怕的解决方案。您的视图可以多次绑定到同一命令(可能是主菜单中的一个按钮,而上下文菜单中的另一个按钮)。如果为同一个命令创建多个实例,则调试可能会更加困难。 (2认同)