Is there a Subject implementation in Rx.NET that functionally resembles BehaviorSubject but emits only if the value has changed?(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实现,但仅在值发生更改时才发出?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:rx.net中是否有功能类似于BehaviorSubject的Subject实现,但仅在值发生更改时才发出?
				
        
 
            
        基础教程推荐
- 经典 Asp 中的 ResolveUrl/Url.Content 等效项 2022-01-01
 - 如何动态获取文本框中datagridview列的总和 2022-01-01
 - 错误“此流不支持搜索操作"在 C# 中 2022-01-01
 - 首先创建代码,多对多,关联表中的附加字段 2022-01-01
 - 从 VS 2017 .NET Core 项目的发布目录中排除文件 2022-01-01
 - 全局 ASAX - 获取服务器名称 2022-01-01
 - 将事件 TextChanged 分配给表单中的所有文本框 2022-01-01
 - JSON.NET 中基于属性的类型解析 2022-01-01
 - 是否可以在 asp classic 和 asp.net 之间共享会话状态 2022-01-01
 - 在 VS2010 中的 Post Build 事件中将 bin 文件复制到物 2022-01-01
 
    	
    	
    	
    	
    	
    	
    	
    	
						
						
						
						
						
				
				
				
				