Last active
March 14, 2020 10:33
-
-
Save udaken/48f2714a5bd12a5932cc868d93fc256f to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Linq; | |
using System.Collections.Generic; | |
using System.ComponentModel; | |
#nullable enable | |
struct NotifiableProperty<T> | |
{ | |
private readonly IEqualityComparer<T> _EqualityComparer; | |
private readonly PropertyChangedEventArgs _ChangedEventArgs; | |
#if SUPPORT_PROPERTY_CHANGING | |
private readonly PropertyChangingEventArgs _ChangingEventArgs; | |
#endif | |
public T Value | |
{ | |
readonly get; | |
private set; | |
} | |
private readonly IEnumerable<PropertyChangedEventArgs>? _DependedPropertiesChangedEventArgs; | |
#if SUPPORT_PROPERTY_CHANGING | |
private readonly IEnumerable<PropertyChangingEventArgs>? _DependedPropertiesChangingEventArgs; | |
#endif | |
public NotifiableProperty(string name, T initValue = default, IEqualityComparer<T>? equalityComparer = null) | |
: this(name, initValue, equalityComparer ?? EqualityComparer<T>.Default, null) | |
{ | |
} | |
public NotifiableProperty(string name, T initValue, params string[] dependedPropertyNames) | |
: this(name, initValue, EqualityComparer<T>.Default, dependedPropertyNames) | |
{ | |
} | |
public NotifiableProperty(string name, T initValue, IEqualityComparer<T> equalityComparer, params string[]? dependedPropertyNames) | |
{ | |
if (name == null) | |
throw new ArgumentNullException(nameof(name)); | |
_ChangedEventArgs = new PropertyChangedEventArgs(name); | |
#if SUPPORT_PROPERTY_CHANGING | |
_ChangingEventArgs = new PropertyChangingEventArgs(name); | |
#endif | |
Value = initValue; | |
_DependedPropertiesChangedEventArgs = dependedPropertyNames?.Select(name => new PropertyChangedEventArgs(name)); | |
#if SUPPORT_PROPERTY_CHANGING | |
_DependedPropertiesChangingEventArgs = dependedPropertyNames?.Select(name => new PropertyChangingEventArgs(name)); | |
#endif | |
_EqualityComparer = equalityComparer ?? throw new ArgumentNullException(nameof(equalityComparer)); | |
} | |
public bool SetValue(PropertyChangedEventHandler? propertyChanged, T value, object? sender = null) | |
#if SUPPORT_PROPERTY_CHANGING | |
=> SetValue(propertyChanged, null, value, sender); | |
public bool SetValue(PropertyChangingEventHandler? propertyChanging, T value) => SetValue(null, propertyChanging, value, object? sender = null); | |
public bool SetValue(PropertyChangedEventHandler? propertyChanged, PropertyChangingEventHandler? propertyChanging, T value, object? sender = null) | |
#endif | |
{ | |
if (!_EqualityComparer.Equals(Value, value)) | |
{ | |
#if SUPPORT_PROPERTY_CHANGING | |
propertyChanging?.Invoke(this, _ChangingEventArgs); | |
if (_DependedPropertiesChangingEventArgs != null) | |
{ | |
foreach (var eventArgs in _DependedPropertiesChangingEventArgs) | |
{ | |
propertyChanging?.Invoke(this, eventArgs); | |
} | |
} | |
#endif | |
Value = value; | |
propertyChanged?.Invoke(sender, _ChangedEventArgs); | |
if (_DependedPropertiesChangedEventArgs != null) | |
{ | |
foreach (var eventArgs in _DependedPropertiesChangedEventArgs) | |
{ | |
propertyChanged?.Invoke(sender, eventArgs); | |
} | |
} | |
return true; | |
} | |
return false; | |
} | |
public static implicit operator T(in NotifiableProperty<T> self) => self.Value; | |
} | |
static class NotifiableProperty | |
{ | |
public static NotifiableProperty<T> Make<T>(string name, T initValue, IEqualityComparer<T>? equalityComparer = null) | |
=> new NotifiableProperty<T>(name, initValue, equalityComparer); | |
public static NotifiableProperty<T> Make<T>(string name, T initValue, IEqualityComparer<T> equalityComparer, params string[] dependedPropertyNames) | |
=> new NotifiableProperty<T>(name, initValue, equalityComparer, dependedPropertyNames); | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment