C#中的可观察主题热和冷

4

我经常遇到这样的情况,希望 UI 元素“监视”底层值 - 假设我显示一个 int - 我想要一个 IObservable,我可以订阅。

我一直在使用 Subject,所以我只需设置它即可。 这很有效... 除了第一次。 如果我设置主题 - 然后稍后通过打开新的 UI 元素订阅它 - 直到下一次更改才触发 onnext。

基本上,我想要像主题一样工作的东西 - 但总是立即对任何新的订阅者进行最新值的 onNext。

我知道我可以自己编写这样的构造 - 但这似乎是一个常见的用例 - 是否存在我错过的标准内容?


3
我认为你正在寻找 BehaviorSubject<T> - Hasan Emrah Süngü
2个回答

8
你需要使用 BehaviorSubject<T> 或者 ReplaySubject<T>BehaviorSubject<T> 会重放单个最近的值,并要求你在构造函数中提供一个初始值。
你可以像这样使用它:
var bs = new BehaviorSubject<int>(0);
bs.Subscribe(x => Console.WriteLine(x));
bs.OnNext(42);
bs.Subscribe(x => Console.WriteLine(x));

这将会在控制台输出0,然后是42,最后再是42

ReplaySubject<T>稍微更加通用。它允许您指定要重新播放的值的数量,但不强制您提供初始值。

var rs = new ReplaySubject<int>(1);
rs.Subscribe(x => Console.WriteLine(x));
rs.OnNext(42);
rs.Subscribe(x => Console.WriteLine(x));

这将产生42,然后将42输出到控制台。

与标准的Subject<T>相比较。

var s = new Subject<int>();
s.Subscribe(x => Console.WriteLine(x));
s.OnNext(42);
s.Subscribe(x => Console.WriteLine(x));

这只会产生42


1
如果您在UI中使用Rx,您应该看一下ReactiveUI。它有方便的扩展.ToProperty等。
_isValid = this.WhenAnyValue(x => x.Username, x => x.Password, (user, password) => !string.IsNullOrEmpty(user) && !string.IsNullOrEmpty(password)).ToProperty(this, x => x.IsValid);

public bool IsValid => _isValid.Value;

这基本上是你正在做的事情:

  • this.WhenAnyValue(x => x.Property) => 将属性转换为可观测对象
  • obs.ToProperty() => 将可观测对象转换为可以绑定到 UI 的属性

两者都与 INotifyPropertyChanged 一起使用。


为什么会有踩票?这基本上是回答“你不必重复造轮子”的问题。 - Krzysztof Skowronek

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接