【问题标题】:How to avoid the use of Subjects in RX如何避免在 RX 中使用 Subjects
【发布时间】:2014-02-17 08:41:44
【问题描述】:

所以我一直在到处读到 Subject<T> 的使用是“不好的”——我有点同意这个推理。

但是,我正在想办法避免使用它并举个例子。

目前,我的持久化配置类有一个抽象类,它上面有一个受保护的Save() 方法,只要更改属性应该持久化类,就会调用该方法。此消息将消息泵送到Subject<T> 上,该消息通过IObservable<T> 接口公开,序列化服务侦听该接口并序列化该类。这在当时似乎是最明显、最简单、最快捷的实现方式。

那么不使用主题的 RX 方法是什么?我会改为公开一个事件并使用Observable.FromEventPattern() 订阅它吗? - 因为这似乎是一种更复杂的方法。

【问题讨论】:

  • 作为一个有趣的问题,你能链接到其中的一些论点吗?我认为我知道的 Rx 不足以回答这个问题,但这是我第一次听说你应该尽量避免使用 Subject
  • @shambulator 检查此链接以获得快速解释:introtorx.com/Content/v1.0.10621.0/18_UsageGuidelines.html

标签: c# system.reactive subject


【解决方案1】:

Subject<T> 的使用并不是那么糟糕——必须有某种“进入 monad”的方式——这是学术上的说法“得到一个IObservable<T> .你需要从某个地方开始。

Subject<T> 的问题更多地出现在从订阅中使用而不是将现有的 observable 链接在一起时。受试者应该存在于您的 Rx 机器的边缘。

如果提供的入口点(例如FromEventFromEventPatternFromAsyncReturnToObservable() 等)都不适合您,那么使用 Subject<T> 是完全有效的。并且没有必要仅仅为了方便使用上述之一而增加额外的复杂性——无论如何,它们中的大多数都使用主题或类似主题的结构。

在你的情况下,听起来像Subject<T> 就好了。您可能需要通过AsObservable() 公开它以隐藏实现细节。

【讨论】:

    【解决方案2】:

    进入 observable 的简单方法是通过 Action

    private Action<ObservableArgs> _action;
    

    创建可观察对象

    public IObservable<ObservableArgs> GetObservable()
    {
        return Observable.FromEvent<ObservableArgs>>(
                    ev => _action += ev, 
                    ev => _action -= ev);
    }
    

    然后使用添加到可观察对象

    public void OnNext(ObservableArgs args)
    {
        _action?.Invoke(args);
    }
    

    【讨论】:

    • 赞成直接回答问题,并说明为什么您不应该避免使用Subjects。因为否则你最终会得到不必要的复杂代码,这会让每个人都对它的意图感到困惑,几个月后可能包括作者自己。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-02
    相关资源
    最近更新 更多