本文介绍了rx.net中是否有功能类似于BehaviorSubject的Subject实现,但仅在值发生更改时才发出?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
rx.net中是否有Subject
实现在功能上类似于BehaviorSubject
,但仅在其发生更改时才发出下一个值?
我对反应式扩展相当陌生,似乎找不到任何类似的东西,尽管此模式感觉像是INotifyPropertyChanged
的自然替代品。
BehaviorSubject<T>
,如下所示。与使用Observable.DistinctUntilChanged
创建可组合的可观察对象相比,这样做有什么缺点吗?
public class DistinctSubject<T> : SubjectBase<T>
{
private readonly BehaviorSubject<T> _subject;
public DistinctSubject(T initialValue) =>
_subject = new BehaviorSubject<T>(initialValue);
public T Value
{
get => _subject.Value;
set => this.OnNext(value);
}
public override bool HasObservers => _subject.HasObservers;
public override bool IsDisposed => _subject.IsDisposed;
public override void Dispose() => _subject.Dispose();
public override void OnCompleted() => _subject.OnCompleted();
public override void OnError(Exception error) => _subject.OnError(error);
public override void OnNext(T value)
{
if (!EqualityComparer<T>.Default.Equals(value, _subject.Value))
{
_subject.OnNext(value);
}
}
public override IDisposable Subscribe(IObserver<T> observer) =>
_subject.Subscribe(observer);
}
推荐答案
浏览了一下BehaviorSubject<T>
类的source code之后,如果OnError
后跟OnNext
:
DistinctSubject<T>
实现的行为似乎会有所不同
var subject = new DistinctSubject<int>(2021);
subject.OnError(new ApplicationException());
subject.OnNext(2022); // throws ApplicationException
此操作将引发,而对BehaviorSubject<T>
执行相同操作将不会引发(仅忽略OnNext
)。
我的建议是在实现中使用DistinctUntilChanged
运算符,如下所示:
public class DistinctSubject<T> : ISubject<T>, IDisposable
{
private readonly BehaviorSubject<T> _subject;
private readonly IObservable<T> _distinctUntilChanged;
public DistinctSubject(T initialValue, IEqualityComparer<T> comparer = default)
{
_subject = new BehaviorSubject<T>(initialValue);
_distinctUntilChanged = _subject.DistinctUntilChanged(
comparer ?? EqualityComparer<T>.Default);
}
public T Value => _subject.Value;
public void OnNext(T value) => _subject.OnNext(value);
public void OnError(Exception error) => _subject.OnError(error);
public void OnCompleted() => _subject.OnCompleted();
public IDisposable Subscribe(IObserver<T> observer) =>
_distinctUntilChanged.Subscribe(observer);
public void Dispose() => _subject.Dispose();
}
如果您担心对象的不必要分配,那么您还不熟悉Rx的精神。此库关注的是功能和易用性,而不是performance或效率!
这篇关于rx.net中是否有功能类似于BehaviorSubject的Subject实现,但仅在值发生更改时才发出?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本站部分内容来源互联网,如果有图片或者内容侵犯您的权益请联系我们删除!