属性 初始化和 'this'
Property initialization and 'this'
我在想是否可以使用对 this
关键字的引用来初始化一个(引用类型)属性(当它的值为 null
时),但是 没有 使用构造函数。
在某些情况下,我不想使用构造函数来初始化 属性 所以,如果没有人访问它,它的值将不会被创建。
此外,如果可能的话,我不喜欢将 属性 声明与其在构造函数中的初始化分开。
一个典型的例子是 MVVM 模式编程的命令声明:
private Command FAddRecordCommand = null;
public Command AddRecordCommand
{
get
{
if (this.FAddRecordCommand == null)
{
this.FAddRecordCommand = new Command(this.AddRecordCommandExecute);
}
return this.FAddRecordCommand;
}
}
private async void AddRecordCommandExecute()
{
//do something
}
我不喜欢把FAddRecordCommand
会员的名字写三遍...
我尝试使用自动实现的属性,但是 this
关键字在初始化时不可访问:
public Command AddRecordCommand { get; } = new Command(this.AddRecordCommandExecute);
编译器抛出错误:关键字'this'在当前上下文中不可用
有没有一种方法可以像自动执行的 属性 提供的那样使用单行声明,但可以访问 this
?
我想出了一个方法来减少代码行数,并使用这种技术访问私有成员:
private Command FAddRecordCommand = null;
public Command AddRecordCommand => LazyInitializer.EnsureInitialized(ref this.FAddRecordCommand, () => new Command(this.AddRecordCommandExecute));
private async void AddRecordCommandExecute()
{
//do something
}
这里我使用了:
- lambda 表达式
=>
替换 属性 的 get
函数
ref
关键字传递对 FAddRecordCommand
成员的引用以允许更改其值
- 一个 lambda 函数
() => new ???
到 return 初始化所需的新值
- LazyInitializer.EnsureInitialized method to assign the initialization value (thanks to Dmitry Bychenko 的建议)
这样就可以使用this
关键字了,声明只需要一行代码,我只访问一次私有成员
将成员作为 ref
传递允许更改其值,而 Func<TProp>
允许仅在初始值为 null
.[=22= 时创建新值]
如果您不喜欢 属性 声明的 lambda 表达式,您仍然可以在一行中声明它:
public Command AddRecordCommand { get { return LazyInitializer.EnsureInitialized(ref this.FAddRecordCommand, () => new Command(this.AddRecordCommandExecute)); } }
这可以使用 null-coalescing assignment operator:
private Command addRecordCommand = null;
public Command AddRecordCommand
=> addRecordCommand ??= new Command(AddRecordCommandExecute);
仅当它为 null 时才分配给 addRecordCommand
,然后 returns 该字段的值。
您似乎在寻找惰性初始化
您可以在 LazyInitializer
的帮助下实现
// Eager command creation
private Command AddRecordCommandExecute() {
//TODO: put the right creation and initialization code here
return new Command(this.AddRecordCommandExecute);
}
// Backing Field
private Command FAddRecordCommand;
// Lazy initialized property:
// AddRecordCommandExecute() will be run once
// on the first AddRecordCommand read
public Command AddRecordCommand => LazyInitializer
.EnsureInitialized(ref FAddRecordCommand, AddRecordCommandExecute);
我在想是否可以使用对 this
关键字的引用来初始化一个(引用类型)属性(当它的值为 null
时),但是 没有 使用构造函数。
在某些情况下,我不想使用构造函数来初始化 属性 所以,如果没有人访问它,它的值将不会被创建。
此外,如果可能的话,我不喜欢将 属性 声明与其在构造函数中的初始化分开。
一个典型的例子是 MVVM 模式编程的命令声明:
private Command FAddRecordCommand = null;
public Command AddRecordCommand
{
get
{
if (this.FAddRecordCommand == null)
{
this.FAddRecordCommand = new Command(this.AddRecordCommandExecute);
}
return this.FAddRecordCommand;
}
}
private async void AddRecordCommandExecute()
{
//do something
}
我不喜欢把FAddRecordCommand
会员的名字写三遍...
我尝试使用自动实现的属性,但是 this
关键字在初始化时不可访问:
public Command AddRecordCommand { get; } = new Command(this.AddRecordCommandExecute);
编译器抛出错误:关键字'this'在当前上下文中不可用
有没有一种方法可以像自动执行的 属性 提供的那样使用单行声明,但可以访问 this
?
我想出了一个方法来减少代码行数,并使用这种技术访问私有成员:
private Command FAddRecordCommand = null;
public Command AddRecordCommand => LazyInitializer.EnsureInitialized(ref this.FAddRecordCommand, () => new Command(this.AddRecordCommandExecute));
private async void AddRecordCommandExecute()
{
//do something
}
这里我使用了:
- lambda 表达式
=>
替换 属性 的 ref
关键字传递对FAddRecordCommand
成员的引用以允许更改其值- 一个 lambda 函数
() => new ???
到 return 初始化所需的新值 - LazyInitializer.EnsureInitialized method to assign the initialization value (thanks to Dmitry Bychenko 的建议)
get
函数
这样就可以使用this
关键字了,声明只需要一行代码,我只访问一次私有成员
将成员作为 ref
传递允许更改其值,而 Func<TProp>
允许仅在初始值为 null
.[=22= 时创建新值]
如果您不喜欢 属性 声明的 lambda 表达式,您仍然可以在一行中声明它:
public Command AddRecordCommand { get { return LazyInitializer.EnsureInitialized(ref this.FAddRecordCommand, () => new Command(this.AddRecordCommandExecute)); } }
这可以使用 null-coalescing assignment operator:
private Command addRecordCommand = null;
public Command AddRecordCommand
=> addRecordCommand ??= new Command(AddRecordCommandExecute);
仅当它为 null 时才分配给 addRecordCommand
,然后 returns 该字段的值。
您似乎在寻找惰性初始化 您可以在 LazyInitializer
的帮助下实现// Eager command creation
private Command AddRecordCommandExecute() {
//TODO: put the right creation and initialization code here
return new Command(this.AddRecordCommandExecute);
}
// Backing Field
private Command FAddRecordCommand;
// Lazy initialized property:
// AddRecordCommandExecute() will be run once
// on the first AddRecordCommand read
public Command AddRecordCommand => LazyInitializer
.EnsureInitialized(ref FAddRecordCommand, AddRecordCommandExecute);