如何公开的IObservable< T>不使用受试对象的属性; T>支持字段 [英] How to expose IObservable<T> properties without using Subject<T> backing field
问题描述
在这个答案一个问题关于受试对象; T>
Enigmativity提到:
In this answer to a question about Subject<T>
Enigmativity mentioned:
顺便说一句,你应该尽量避免使用对象的。在
一般规则是,如果你使用一个主题,那么你正在做
不对劲。
as an aside, you should try to avoid using subjects at all. The general rule is that if you're using a subject then you're doing something wrong.
我经常用科目为后盾字段的IObservable
性质,这将对接收前的日子可能已经.NET事件。例如而不是像
I often use subjects as backing fields for IObservable
properties, which would have probably been .NET events in the days before Rx. e.g. instead of something like
public class Thing
{
public event EventHandler SomethingHappened;
private void DoSomething()
{
Blah();
SomethingHappened(this, EventArgs.Empty);
}
}
我可以做
I might do
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);
}
}
所以,如果我想避免使用主题
什么是做这种事情的正确方法是什么?或者我,我应该坚持在我的接口使用。NET的事件,甚至当他们将通过接收代码被消耗(所以大概 FromEventPattern
)?
So, if I want to avoid using Subject
what would be the correct way of doing this kind of thing? Or I should I stick to using .NET events in my interfaces, even when they'll be consumed by Rx code (so probably FromEventPattern
)?
此外,为什么使用主题更多的细节
喜欢,这是一个坏主意,将是有益的。
Also, a bit more details on why using Subject
like this is a bad idea would be helpful.
更新:为了使这个问题有点更具体的,我说的是使用受试对象; T>
作为一种非接收代码来获得(也许你正在与其他一些遗留代码工作)到RX的世界。那么,是这样的:
Update: To make this question a bit more concrete, I'm talking about using Subject<T>
as a way to get from non-Rx code (maybe you're working with some other legacy code) into the Rx world. So, something like:
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型品牌你重写虚拟方法为得到这只是碰巧通知的方式
Where, instead of using events, the LegacyApiForSomeHardware type makes you override virtual methods as a way of getting "this just happened" notifications.
推荐答案
在一个的answer的Rx论坛,戴夫·塞克斯顿(中的Rxx )表示,由于部分回答了一句:
In an answer on the Rx forum, Dave Sexton (of Rxx), said as part an answer to something:
主题是接收的状态的组件。他们是在$ B $有用的B您需要创建一个事件像观察到作为一个字段或本地
变量。
Subjects are the stateful components of Rx. They are useful for when you need to create an event-like observable as a field or a local variable.
这正是与这个问题发生的事情,他还写上的要使用主题或不使用主题它与结论:
Which is exactly what's happening with this question, he also wrote an in-depth follow up blog post on To Use Subject Or Not To Use Subject? which concludes with:
< STRONG>什么时候应该使用一个主题
在以下全部为真:?
- 你没有可观察的或任何可以被转换成一个。
- 您需要使用热观测。
- 您观察到的范围是一个类型。
- 您不需要定义一个类似的事件,已经不存在类似的事件。
- you don't have an observable or anything that can be converted into one.
- you require a hot observable.
- the scope of your observable is a type.
- you don't need to define a similar event and no similar event already exists.
为什么要使用在这种情况下一个主题?
由于你有没有选择!
所以,回答的内部问题的细节,为什么使用主题就像这是一个坏主意 - 这不是一个坏主意,这是少数地方之一是使用主题是做事的正确方法。
So, answering the inner question of "details on why using Subject like this is a bad idea" - it's not a bad idea, this is one of the few places were using a Subject is the correct way to do things.
这篇关于如何公开的IObservable< T>不使用受试对象的属性; T>支持字段的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!