I was wandering if I could initialize a (reference type) property (when its value is null
) using a reference to this
keyword, but without using the constructor.
In some cases I do not want to use the constructor to initialize the property so, if no one accesses it, its value will not be created.
Furthermore, I don't like to separate the property declaration from it's initialization in the constructor, if possible.
A typical example is a Command declaration for MVVM pattern programming:
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
}
I don't like to write three times the name of the FAddRecordCommand
member...
I tried with Auto-implemented properties, but the this
keyword is not accessible in the initialization:
public Command AddRecordCommand { get; } = new Command(this.AddRecordCommandExecute);
The compiler throws the error: Keyword 'this' is not available in current context
Is there a way to use the one-line declaration like the Auto-Implemented property provides, but making access to this
?
I figured out a way to reduce the lines of code, and the access to the private member, with this technique:
private Command FAddRecordCommand = null;
public Command AddRecordCommand => LazyInitializer.EnsureInitialized(ref this.FAddRecordCommand, () => new Command(this.AddRecordCommandExecute));
private async void AddRecordCommandExecute()
{
//do something
}
Here I used:
=>
to replace the get
function of the propertyref
keyword to pass a reference to the FAddRecordCommand
member to allow its value to be changed() => new ???
to return the new value needed for initializationThis way the this
keyword is available, the declaration requires only one line of code, and I access the private member only once.
passing the member as ref
allows its value to be changed, and the Func<TProp>
allows the new value to be created only when initial value is null
.
If you don't like lambda expressions for property declaration, you can still declare it in one line:
public Command AddRecordCommand { get { return LazyInitializer.EnsureInitialized(ref this.FAddRecordCommand, () => new Command(this.AddRecordCommandExecute)); } }