Last active
April 22, 2021 10:00
-
-
Save runceel/95aae4cb6360ab1099b20ea067e00d14 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 Reactive.Bindings; | |
using Reactive.Bindings.Extensions; | |
using System; | |
using System.Linq; | |
using System.Reactive; | |
using System.Reactive.Disposables; | |
using System.Reactive.Linq; | |
using System.Reactive.Subjects; | |
namespace ConsoleApp5 | |
{ | |
class Program | |
{ | |
static void Main(string[] args) | |
{ | |
var p = new Person(); | |
// 未変更なので false | |
Console.WriteLine(p.IsModified.Value); | |
p.Name.Value = "xxx"; | |
// 変更したので true | |
Console.WriteLine(p.IsModified.Value); | |
p.Reset(); | |
// Reset したので false | |
Console.WriteLine(p.IsModified.Value); | |
} | |
} | |
class Person : IDisposable | |
{ | |
private readonly CompositeDisposable _disposables = new CompositeDisposable(); | |
private readonly ISubject<Unit> _resetNotifyer; | |
public IReadOnlyReactiveProperty<bool> IsModified { get; } | |
public ReactiveProperty<string> Name { get; } = new ReactiveProperty<string>(); | |
public ReactiveProperty<int> Age { get; } = new ReactiveProperty<int>(); | |
public Person() | |
{ | |
(IsModified, _resetNotifyer) = ReactivePropertyUtils.CreateIsModifiedProperty(Name, Age); | |
_disposables.Add(Name); | |
_disposables.Add(Age); | |
_disposables.Add(IsModified); | |
} | |
public void Reset() => _resetNotifyer.OnNext(Unit.Default); | |
public void Dispose() | |
{ | |
_disposables.Dispose(); | |
} | |
} | |
static class ReactivePropertyUtils | |
{ | |
/// <summary> | |
/// 受け取った ReactiveProperty に変更があったかどうかを保持する IReadOnlyReactiveProperty を作成する。 | |
/// </summary> | |
/// <param name="properties">変更を監視する対象の ReactiveProperty</param> | |
/// <returns>変更があった場合に true になる IReadOnlyReactiveProperty と、false にリセットするための ISubject。ISubject に OnNext(Unit.Default) を呼び出すことで IsModified が false にリセットされます。</returns> | |
public static (IReadOnlyReactiveProperty<bool> IsModified, ISubject<Unit> ResetNotifyer) CreateIsModifiedProperty( | |
params IReactiveProperty[] properties) | |
{ | |
var subject = new Subject<Unit>(); | |
return ( | |
properties.Select(x => x.PropertyChangedAsObservable().Select(_ => true)).Append(subject.Select(_ => false)) | |
.Merge() | |
.ToReadOnlyReactivePropertySlim(false), | |
subject | |
); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment