如何避免在RX中使用Subjects

15

我到处看到使用Subject<T>是“不好”的,而我也同意这种说法。

但是,我正在尝试想出避免使用它的最佳方法,并且有一个例子。

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

那么,如何使用RX来做到这一点而不使用Subject呢?我应该公开一个事件并使用Observable.FromEventPattern()来订阅它吗?-因为这似乎是一种更复杂的方法。


1
有趣的是,您可以提供一些这些论点的链接吗?我认为我还不了解足够的Rx来回答这个问题,但这是我第一次听说您应该尽量避免使用Subject - anton.burger
2
@shambulator 请查看以下链接,以获取快速解释:http://introtorx.com/Content/v1.0.10621.0/18_UsageGuidelines.html - jnovo
2个回答

18
并不是说使用Subject<T>是不好的 - 必须有某种方式来 "进入monad" - 这是学术上说法,意思是 "获取IObservable<T>"。你需要从某个地方开始。 Subject<T>的问题更多的是当它从订阅中使用而不是将现有的observables链接在一起时发生。Subjects应该只存在于您的Rx机器的边缘。
如果提供的入口点(例如FromEventFromEventPatternFromAsyncReturnToObservable()等)都不适用于您,则使用Subject<T>是完全有效的。并且没有必要添加额外的复杂性来促进使用上述方法之一 - 大多数使用subjects或类似subject的结构在底层。
在您的情况下,听起来Subject<T>就可以了。您可能希望通过AsObservable()公开它,以隐藏实现细节。

3

通过Action是进入Observable的一种简单方法

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);
}

2
因为您直接回答了问题并展示了为什么不应该避免使用“Subject”,所以我点赞了。否则,您最终会得到一个不必要复杂的代码,让每个人都对其意图感到困惑,包括几个月后的作者自己。 - Theodor Zoulias

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