C# 为什么RelayCommand通常使用延迟初始化?

C# 为什么RelayCommand通常使用延迟初始化?,c#,xaml,mvvm,data-binding,lazy-initialization,C#,Xaml,Mvvm,Data Binding,Lazy Initialization,使用Josh Smith时,我看到的大多数示例都使用惰性初始化,例如: public class ViewModel { private ICommand myCommand; public ICommand MyCommand { get { if (myCommand == null) { myCommand = new RelayCommand(p =&

使用Josh Smith时,我看到的大多数示例都使用惰性初始化,例如:

public class ViewModel
{
    private ICommand myCommand;

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

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

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

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

    public ICommand MyCommand
    {
        get;
        private set;

    }

    // ... stuff ...
}
在这里使用惰性初始化有什么好处?在设置绑定时,它必须调用get属性,因此我看不出在构造函数中使用此方法的原因


我在这里遗漏了什么吗?

实际上,WPF和Silverlight在每个绑定中只会获得一次中继命令,因此您根本不需要存储备份字段:

public ICommand MyCommand
{
    get
    {
        return new RelayCommand(p => DoSomething());
    }
}

因此,尽管按照您的建议在.ctor中创建它没有什么错,但几乎没有理由这样做。

您是对的。RoutedCommands的延迟初始化没有任何意义,因为它们非常轻量级,只要视图绑定到它,它们就会被加载。“WPF和Silverlight将在每个绑定中只获得一次中继命令”——我知道在实践中这是正确的。但是,鉴于文档没有承诺这种行为,每次检索属性值时创建一个新对象真的那么明智吗?那天发生了什么事,Microsoft出于任何原因决定让您的模型对象保留命令对象引用而不是将其缓存在某个地方更合理,并且他们每次需要时都从属性中获取值?@Peter Duniho:不仅仅是Microsoft;我的视图模型始终直接从自己的方法调用其命令(和CanExecute()。所以,不,每次都创建一个新实例是不明智的。@BoltClock:好的。我将更明确地介绍@Peter Duniho中的场景:因此我意识到为什么我没有使用字段/属性初始值设定项——因为我的命令本身也调用视图模型实例方法。当然,我可以将这些初始化移到构造函数中,尽管我不确定这会有多大不同。我选择了根本不重构。这是一个可怕的解决方案。您的视图可以多次绑定到同一命令(可能是主菜单中的一个按钮和上下文菜单中的另一个按钮)。如果为同一命令创建多个实例,调试可能会更加困难。