I follow this tutorial on commands in MVVM:
https://metanit.com/sharp/wpf/22.3.php
Here's an example code of a Command from the tutorial
private RelayCommand addCommand;
public RelayCommand AddCommand
{
get
{
return addCommand ??
(addCommand = new RelayCommand(obj =>
{
Phone phone = new Phone();
Phones.Insert(0, phone);
SelectedPhone = phone;
}));
}
}:
As I understand the logic, we have a private backing field addCommand
and public property AddCommand
which only has a getter. In said getter the field addCommand is tested against null
. If addCommand != null
then its value is returned. Otherwise a new exemplar of RelayCommand
class is returned. But since AddCommand doesn't have a setter, including a private one, doesn't it mean addCommand
field will always return null
? Why test against null
a field that will always return null
? Why keep such a field at all?
You might be missing the part in C# where any assignment returns the value that was assigned, as a result
x = 1
Returns 1
This means you can do
y = x = 1
And y ends up as 1 too, because the result of x=1
is 1 and this is assigned to y
As a result the pattern you see offers a one time creation of a value for your addCommand
; if addCommand
has a value then the existing value is returned, if it does not (i.e. it is null
) then the ??
ensures the right hand side is executed which performs an assignment: addCommand
receives a new value, which is then returned as the "result of the assignment" (and ultimately is returned as the result of the get). This addCommand
then survives to the next time it's called, meaning that the creation of it is only done once, and upon first demand rather than by default upon creation of the enclosing class (we call it lazy loading/lazy instantiation..)
private int x = null;
//if x is not null return x otherwise return: (assign 1 to x and return 1)
get { return x ?? (x = 1); }
Footnote:
You might consider refactoring your code as:
get
{
if(addCommand == null){
addCommand = new RelayCommand(obj =>
{
Phone phone = new Phone();
Phones.Insert(0, phone);
SelectedPhone = phone;
}
}
return addCommand;
}
It's not significantly longer, and it's equivalently performant, so if you'd have understood it better, then the time it saved you in not having to ask on SO about it would forever be profit :) - sometimes C# devs can go too far in the quest for finding some compact, one-line way to express intent and end up with something that is equally "computer readable" but less "human readable", and if you can't understand it at a glance it might well be a needless waste of your time every time you come to look at it
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments