using System.Collections.Concurrent; using System.ComponentModel; using System.Runtime.CompilerServices; namespace Remotely.Desktop.Shared.Reactive; public class ObservableObject : INotifyPropertyChanged { private readonly ConcurrentDictionary _backingFields = new(); public event PropertyChangedEventHandler? PropertyChanged; public void NotifyPropertyChanged([CallerMemberName] string propertyName = "") { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } protected T? Get([CallerMemberName] string propertyName = "") { if (_backingFields.TryGetValue(propertyName, out var value) && value is T typedValue) { return typedValue; } return default; } protected T Get(T defaultValue, [CallerMemberName] string propertyName = "") { if (_backingFields.TryGetValue(propertyName, out var value) && value is T typedValue) { return typedValue; } return defaultValue; } protected void Set(T newValue, [CallerMemberName] string propertyName = "") { _backingFields.AddOrUpdate(propertyName, newValue, (k, v) => newValue); NotifyPropertyChanged(propertyName); } }