I need to monitor for changes of nullable Foo
, including Foo = null
or changes of any property like Foo.Bar = 123
.
So I am using this syntax (similar to recommended):
WhenAnyValue(o => o.Foo, o => o.Foo!.Bar, (foo, bar) => (foo, bar))
to subscribe to changes of both Foo
and Bar
of my view model:
public class VM : ReactiveObject{ [Reactive] public Foo? Foo { get; set; }}public class Foo : ReactiveObject{ [Reactive] public int Bar { get; set; }}
However, this will run subscriber multiple time with stale values. After Foo = null
subscriber is called with previous value of Bar
and after Foo = new()
subscriber is called twice: with previous value of Bar
and with correct one. This can be demonstrated with following code:
var vm = new VM() { Foo = new Foo { Bar = 1 } };vm.WhenAnyValue(o => o.Foo, o => o.Foo!.Bar, (foo, bar) => (foo, bar)).Subscribe(o => Console.WriteLine($"{o.foo?.GetHashCode()} {o.bar}"));vm.Foo = null; // #1vm.Foo = new Foo { Bar = 2 }; // #2
The output looks like this:
58225482 1 1 << stale Bar32347029 1 << stale Bar32347029 2 << extra call
Instead I want something like this:
58225482 1 032347029 2
In other words, I don't want to have stale values and extra subscriber call if possible.
The Foo == null
check inside subscriber will solve #1. But maybe there is a different rx solution to such a problem? Or is moving null check outside of subscriber somehow is also ok?
As for #2, I have only idea of workaround with storing previous value of Foo
and ignore first call if previous value was null
. Again, it's a procedural way of programming. How this should be done in rx world of programming?