每次在属性getter中返回新的ICommand是不好的吗?

10

这段代码是否值得编写:

RelayCommand _saveCommand;
public ICommand SaveCommand
{
    get
    {
        if (_saveCommand == null)
        {
            _saveCommand = new RelayCommand(this.Save);
        }
        return _saveCommand;
    }
}

而不是每次只返回新对象:

public ICommand SaveCommand
{
    get { return new RelayCommand(this.Save); }
}

据我所知,命令获取器很少使用,而且RelayCommand的构造函数非常快速。编写更长的代码是否更好?


2
你关心什么?代码长度、内存使用等吗? 如果是长度的话,你可以将第一个示例缩短为一行:return _saveCommand ?? (_saveCommand = new RelayCommand(this.Save)); - Brunner
为什么不这样做:readonly RelayCommand _saveCommand=new RelayCommand(Save); public ICommand SaveCommand {get { return _saveCommand; }} - Steve B
或者您也可以在类的构造函数中添加 _saveCommand=new RelayCommand(Save); - Steve B
1
你需要保留一个命令对象的引用,对吧?如果每次都返回一个新的RelayCommand,并且你没有保留命令对象的引用,那么你该如何管理这些返回命令的CanExecute呢? - Eren Ersönmez
@ErenErsönmez CanExecute 委托也可以传递给构造函数,而 CanExecuteChanged 则使用 System.Windows.Input.CommandManager 进行管理(请参见 RelayCommand 源代码的链接)。 - Poma
3个回答

11

我喜欢空值合并运算符

public ICommand SaveCommand 
{ 
    get { return _saveCommand ?? (_saveCommand = new RelayCommand(this.Save); }
}

如果左操作数不为 null,则返回左操作数;否则返回右操作数。


1
虽然我也喜欢??,但我觉得它不是问题的答案。我认为问题归结为“每次返回新对象还是重用旧对象”。 - Brunner
@Brunner:是的,我同意。但问题也包含了“编写长代码是否更好”的问题,而??可以让代码变得更短。无论如何,我本来想编辑问题以包含更多信息,但其他答案已经发布了。 - Fredrik Hedblad
我喜欢这个模式,但我正在尝试为调用异步void方法的命令执行它。这样做是不行的:get => _submitCommand ?? (_submitCommand = new Command(async () => await Submit_Clicked())); - Chucky

6

这种设计可能会误导你的类的用户。例如,他们可以在循环中读取属性的值,而循环有数千次迭代。这将创建许多新对象,用户可能不会预料到。

请参阅StyleCop警告CA1819:属性不应返回数组的文档 - 这是一个非常相似的问题。

通常,用户不会理解调用此类属性的不良性能影响。具体来说,他们可能将属性用作索引属性。

此外,SaveCommand == SaveCommand将为false。我认为这是反直觉的。

总之,这可能不是最好的设计,但是,如果您代码的用户知道它的工作原理并知道如何正确使用它,则可以接受。


1

是的,每次返回一个新对象都很糟糕。为什么要这样做呢?如果由于任何原因,该getter被多次调用,那么每次都会在内存中创建新对象。如果您只对这个孤立的实例这样做,那么情况就不那么可怕了。但是,如果您养成了这种编程习惯,就会创建难以找到的问题,并且代码库难以维护。最好始终保持简单、干净和优雅,最终得到一个漂亮、干净、易于维护的代码库。

顺便说一下,您可以在声明字段时初始化它:

RelayCommand _saveCommand = new RelayCommand(this.Save);

那么你的getter只需要包含这个:

return _saveCommand;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接