ObservableProperty
Another useful attribute from CommunityToolkit.Mvvm, by using ObservableProperty, we can get rid of ObservableObject.SetProperty we mentioned earlier.
How is ObservableObject.SetProperty been used
SetProperty saves us from the boilerplate for each observable property.
cs
class Foo : ObservableObject
{
private bool _isChecked;
public bool IsChecked
{
get => _isChecked;
set => SetProperty(ref _isChecked, value);
}
}1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
ObservableProperty Approach
ObservableProperty saves even more. It's empowered by source generator, which needs an extra partial mark for emiting code at somewhere else.
cs
partial class Foo : ObservableObject // requires partial to emit code
{
[ObservableProperty] private bool _isChecked;
}1
2
3
4
2
3
4
The code generated is like the following, performs the similar logic as SetProperty.
cs
partial class Foo
{
/// <inheritdoc cref="_isChecked"/>
[global::System.CodeDom.Compiler.GeneratedCode("CommunityToolkit.Mvvm.SourceGenerators.ObservablePropertyGenerator", "8.3.0.0")]
[global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
public bool IsChecked
{
get => _isChecked;
set
{
if (!global::System.Collections.Generic.EqualityComparer<bool>.Default.Equals(_isChecked, value))
{
// also generates a lot methods for the field only.
OnIsCheckedChanging(value);
OnIsCheckedChanging(default, value);
OnPropertyChanging(global::CommunityToolkit.Mvvm.ComponentModel.__Internals.__KnownINotifyPropertyChangingArgs.IsChecked);
_isChecked = value;
OnIsCheckedChanged(value);
OnIsCheckedChanged(default, value);
OnPropertyChanged(global::CommunityToolkit.Mvvm.ComponentModel.__Internals.__KnownINotifyPropertyChangedArgs.IsChecked);
}
}
}
// ...
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26