多次调用.WhenAny(...).ToPropertyEx(...)是否会互相覆盖?
结论:这是预期行为,并非Bug
问题复现说明
你给出的两次绑定同属性的代码如下:
this.WhenAnyValue(x => x.SomeInt) .Select(x => "Bar" + x) .ToPropertyEx(this, x => x.SomeString); this.WhenAnyValue(x => x.SomeInt) .Select(x => "Foo" + x) .ToPropertyEx(this, x => x.SomeString);
测试时观测到只有后调用的绑定生效,交换绑定顺序后输出前缀同步变化,完全符合ReactiveUI的设计逻辑。
核心原因
ToPropertyEx的本质是给目标可观察属性创建一个独立的订阅绑定,每个绑定会在源Observable推送新值时,直接为目标属性赋值。
你两次绑定的源WhenAnyValue(x => x.SomeInt)是同源的,当SomeInt发生变化时,两个绑定的回调会按订阅先后顺序执行:第一个绑定先把SomeString赋值为Bar{x},第二个绑定紧接着把SomeString赋值为Foo{x},最终观测到的永远是后执行的第二个绑定的赋值结果。
过滤场景不生效的说明
如果添加了过滤条件后仍只有最后一个绑定生效,大概率是过滤条件写法存在问题,或者属性值观测时机有误,被其他逻辑覆盖了。
正常来说如果两个流的过滤条件互斥,满足条件的流会单独推送值更新属性,不会出现覆盖问题。
正确实现方案
如果需要多个逻辑共同控制同一个可观察属性的值,应该先合并多个流,再做一次绑定,避免多次绑定出现值覆盖问题:
// 奇数场景流 var barStream = this.WhenAnyValue(x => x.SomeInt) .Where(x => x % 2 == 1) .Select(x => "Bar" + x); // 偶数场景流 var fooStream = this.WhenAnyValue(x => x.SomeInt) .Where(x => x % 2 == 0) .Select(x => "Foo" + x); // 合并流后统一绑定 Observable.Merge(barStream, fooStream) .ToPropertyEx(this, x => x.SomeString);
内容的提问来源于stack exchange,提问作者Russell Bearden
相关产品推荐
相关产品推荐

