Is it safe to call new RelayCommand (ICommand) in Expression-Bodied Properties(在表达式体属性中调用新的RelayCommand(ICommand)是否安全)
问题描述
使用表达式体属性,我们可以创建RelayCommand
,如下所示
public RelayCommand Command => _command ?? (_command = new RelayCommand(CommandExecute));
不过,这也是可能的
public RelayCommand Command => new RelayCommand(CommandExecute);
显然,这会在每次调用属性getter
时创建一个新的RelayCommand。尽管我看到的一些评论说底层管道只创建一个命令...
有人对这个问题有明确的答案吗?
推荐答案
有人对这个问题有明确的答案吗?
文档并未承诺只检索一次属性值。因此,您必须假定它可以多次检索它。
当然,在实践中,这种假定的行为可能永远不会发生。如果属性从未发生属性更改通知,则一旦检索到该属性,就再也不会检索该属性,当然,只读属性也永远不会有属性更改通知。所以你可能可以逃脱惩罚。但就我个人而言,我不会冒险。如果底层实现发生变化,或者您的假设因任何原因而错误,那么拥有同一命令的两个或多个实例将是一个问题,至少在该命令引发CanExecuteChanged
事件的情况下是这样。我的意思是,我猜如果CanExecute()
状态不变,您可以拥有任意多个对象的副本,并且它们的工作方式完全相同。但是,如果它可以更改,那么您最终可能会在错误的命令对象上引发事件,而这个对象没有人在监听。
这不仅仅是学术问题。Microsoft或某一天可能使用的基于XAML/MVVM的API的其他实现者不仅可以选择放弃存储命令对象引用,而是依赖于始终能够从模型对象中检索它,而且在模型对象本身中从属性中检索命令对象是常见的做法。命令属性被多次读取的情况完全有可能发生,并且值得担心。
更重要的是,我看不到这两个选项背后的动机。"每次都创建一个新的"在我看来显然是错误的,即使你可以逃脱惩罚。而且懒惰的初始化看起来像是没有任何好处的过于复杂的代码。毕竟,在创建模型对象之后,几乎总是发生的下一件事是属性被绑定到UI,因此将在那时检索命令属性。延迟初始化最多会将基础字段的初始化延迟几毫秒(通常比这要短得多)。
如果您放弃了惰性初始化,则可以使用自动属性:
public RelayCommand Command { get; } = new RelayCommand(CommandExecute);
没有显式字段!好多了,我也是。
当然,请注意,要使用该语法,CommandExecute()
必须是static
成员。大多数命令确实需要访问模型实例,因此上面的命令不适用于这些命令。
lazy-init模式流行的一个原因可能是它允许使用字段初始值设定项语法,作为通常的"不允许在字段初始值设定项中使用实例成员"规则的漏洞。
就我个人而言,我仍然会选择使用当前实例的命令的构造内初始化(这对于只读的自动属性和hellip很好;您仍然不需要显式的支持字段)。在此方案中,lazy-init似乎是不成熟的和错误优化。
这篇关于在表达式体属性中调用新的RelayCommand(ICommand)是否安全的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:在表达式体属性中调用新的RelayCommand(ICommand)是否安全
基础教程推荐
- 将 Office 安装到 Windows 容器 (servercore:ltsc2019) 失败,错误代码为 17002 2022-01-01
- 如何在 IDE 中获取 Xamarin Studio C# 输出? 2022-01-01
- 将 XML 转换为通用列表 2022-01-01
- rabbitmq 的 REST API 2022-01-01
- SSE 浮点算术是否可重现? 2022-01-01
- 如何激活MC67中的红灯 2022-01-01
- 为什么Flurl.Http DownloadFileAsync/Http客户端GetAsync需要 2022-09-30
- 有没有办法忽略 2GB 文件上传的 maxRequestLength 限制? 2022-01-01
- MS Visual Studio .NET 的替代品 2022-01-01
- c# Math.Sqrt 实现 2022-01-01