Initial community discussion thread: dotnet/csharplang#140
public List<int> Prop => field ??= new();
public Foo Prop => LazyInitializer.EnsureInitialized(ref field, CalculateFoo);
public string Prop { get => field ?? parent.Prop; set; }
public string Prop
{
get => field ?? parent.Prop;
set => field = value == parent.Prop ? null : value;
}
public string Prop { get; set => field = value.Trim(); }
public int Prop
{
get;
set => field = value < 1 ? throw new ArgumentOutOfRangeException(...) : value;
}
public INotifyCollectionChanged? Collection
{
get;
set
{
field?.CollectionChanged -= OnCollectionChanged;
field = value;
field?.CollectionChanged += OnCollectionChanged;
}
}
public int Prop
{
get;
set
{
if (field == value) return;
field = value;
CalculateTotals();
}
}
This is one of the most vociferously popular use cases, for those using INPC today.
class C : ViewModel
{
public string Prop { get; set => Set(ref field, value); }
}
// Common genre of helper method:
abstract class ViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler? PropertyChanged;
protected bool Set<T>(
[NotNullIfNotNull(nameof(value))] ref T field,
T value,
[CallerMemberName] string? propertyName = null);
}
Console.WriteLine(default(S).DefaultsToTrue); // True
struct S
{
public bool DefaultsToTrue { get => !field; set => field = !value; }
}