在一个有关Subject<T>
的问题中,Enigmativity在这个回答中提到:
顺便说一句,你应该尽量避免使用subjects。通常情况下,如果你使用了subject,那么你可能做错了些什么。
我经常使用subjects作为IObservable
属性的备用字段,在Rx出现之前它们可能会是.NET事件。例如,代替这样的东西
public class Thing
{
public event EventHandler SomethingHappened;
private void DoSomething()
{
Blah();
SomethingHappened(this, EventArgs.Empty);
}
}
我可能会这样做
public class Thing
{
private readonly Subject<Unit> somethingHappened = new Subject<Unit>();
public IObservable<Unit> SomethingHappened
{
get { return somethingHappened; }
}
private void DoSomething()
{
Blah();
somethingHappened.OnNext(Unit.Default);
}
}
那么,如果我想避免使用 Subject
,应该怎样正确地完成这种操作?或者,我应该坚持在我的接口中使用.NET事件,即使它们将被Rx代码(因此可能是FromEventPattern
)使用吗?
另外,更详细地解释为什么像这样使用 Subject
是个坏主意会有所帮助。
更新:为了让这个问题更具体,我在谈论使用 Subject<T>
作为一种从非Rx代码(也许你正在使用其他遗留代码)进入Rx世界的方式。 所以,类似于:
class MyVolumeCallback : LegacyApiForSomeHardware
{
private readonly Subject<int> volumeChanged = new Subject<int>();
public IObservable<int> VolumeChanged
{
get
{
return volumeChanged.AsObservable();
}
}
protected override void UserChangedVolume(int newVolume)
{
volumeChanged.OnNext(newVolume);
}
}
LegacyApiForSomeHardware是一种类型,它让你通过重写虚方法来获取“刚刚发生”的通知,而不是使用事件。