这个让我夜不能寐。假设我有一个简单的界面:
public interface INotifier
{
IObservable<string> Messages { get; }
void SendMessage(string message);
}
如果不在内部使用Subject<string>
或等效的有状态构造,我如何实现此接口?
我并不意味着这是一场教条式的辩论,更多的是思想实验。如果这是一个真正的问题,我不会考虑使用一个主题来做这件事。我只是好奇,如果有人采取行动,我没有考虑他们可以分享,只是可能扩大我们的集体前景。
答案 0 :(得分:4)
查看ISubject<T>
的定义(稍微简化):
interface ISubject<T> : IObserver<T>, IObservable<T>
{
void OnValue(T value);
void OnError(Exception error);
void OnCompleted();
IDisposable Subscribe(IObserver<T> observer);
}
现在看一下INotifier
的概念等效定义:
interface INotifier : IObservable<string>
{
IDisposable Subscribe(IObserver<string> observer);
void OnValue(string value);
}
你看到了问题吗?您的INotifier
完全描述了主题的概念,减去OnError
和OnCompleted
。虽然不是很明显,但你的问题可以简化为:“如何在没有主题的情况下实现主题?”
在某些时候,订阅者观察到的每个通知都必须来自某个地方。如果这个最终来源是“冷”,你不应该在任何地方需要主题。如果该最终来源是“热门”,则意味着这些值是从您的程序外部推送给您的,而不是IObservable<T>
,您必须使用主题。这是不可避免的。在这些情况下,目标是将主题直接置于最终来源。
答案 1 :(得分:1)
我同意@Timothy Shields的观点。您正在尝试在不使用主题的情况下实施ISubject
。我也明白你已经简化了界面以保持问题集中(这是值得赞赏的)。但是在这种情况下,我认为需要退后一步,查看系统的分层/设计,以了解为什么你有一个看似是事件代理的类。大多数情况下,当我看到一个主题被使用时,它是有效的(1%的时间),或者实际上系统的结构是需要解决的问题。