在c#中,以下
之间存在差异//syntax 1
private ICommand newWindowCommand;
public ICommand NewWindowCommand
{
get
{
return newWindowCommand = newWindowCommand ?? new MVVM.RelayCommand(...);
}
}
//syntax 2
private ICommand newWindowCommand;
public ICommand NewWindowCommand
{
get
{
return newWindowCommand ?? new MVVM.RelayCommand(...);
}
}
//syntax 3 the usual way
private ICommand newWindowCommand;
public ICommand NewWindowCommand
{
get
{
if (newWindowCommand==null)
{
newWindowCommand = new MVVM.RelayCommand(...);
}
return newWindowCommand;
}
}
在第2种情况下是否将newWindowCommand设置为已返回的值,还是必须按照情况1分配它?
答案 0 :(得分:4)
如果未分配newWindowCommand
2
案例3与案例1相同,但还有很长的路要走。
使用此:(在我的代码中出现很多)
get {
return newWindowCommand ?? (newWindowCommand = new MVVM.RelayCommand(...));
}
首先会检查是否已分配newWindowCommand
。如果没有,它将创建一个新实例,分配并返回它。
与案例1(括号)不同,因为??
运算符的higher precedence比=
强。{
因此,(
和)
可确保首先执行=
,然后??
。
答案 1 :(得分:2)
案例2不会设置newWindowCommand
,因此每次都会调用new MVVM.RelayCommand(...);
。
答案 2 :(得分:2)
你的案例2和3在功能上是相同的,但是IL是不同的,并且取决于它们可能因此的优化而具有不同的特征,例如:线程安全。这不是我建议选择的东西,除非它是这段代码的确定问题。
是否或
get {
return newWindowCommand ?? (newWindowCommand = new MVVM.RelayCommand(...));
}
或
get {
return newWindowCommand = newWindowCommand ?? new MVVM.RelayCommand(...);
}
可能会以相同的优化代码结束,因为后者中的分配可能是多余的。
使用Lazy<T>
Lazy<IComand> newWindowCommand = new Lazy<ICommand>(()=> new MVVM.RelayCommand(...));
get {
return newWindowCommand.Value;
}
您可以进一步自定义初始化,例如关于线程安全。如果没有线程安全问题,我建议你选择一个你认为更具可读性的人,并表达最纯粹的意图。如果您有线程安全问题,那么无论您认为哪个更具可读性,我都建议您使用Lazy<T>
。线程安全很难做到正确,所以我总是使用BCL实现
答案 3 :(得分:1)
当然,在语法2的情况下,newWindowCommand
将保持酉(null)
答案 4 :(得分:1)
除非您在代码中的其他地方设置newWindowCommand字段,否则在案例1和2中它将始终为null。
这种懒惰初始化的另一件事。如果多个线程同时访问您的命令属性,则可以多次初始化新的RelayCommand。您需要同步代码:
get
{
lock(syncobject)
{
return newWindowCommand ?? (newWindowCommand = MVVM.RelayCommand(...));
}
}
ICommand方法可能永远不会用于其他情况,而不是通过绑定。绑定机制只会检索一次命令,因此您可能不需要在视图模型中存储命令引用。
public ICommand NewWindowCommand
{
get
{
return new MVVM.RelayCommand(...);
}
}