Appendix C: Usage guidelines
This is a list of quick guidelines intended to help you when writing Rx queries.
- Members that return a sequence should never return null. This applies to
IEnumerable<T>
andIObservable<T>
sequences. Return an empty sequence instead. - Dispose of subscriptions only if you need to unsubscribe from them early.
- Always provide an
OnError
handler. - Avoid blocking operators such as
First
,FirstOrDefault
,Last
,LastOrDefault
,Single
,SingleOrDefault
andForEach
.; use the non-blocking alternative such asFirstAsync
. - Avoid switching back and forth between
IObservable<T>
andIEnumerable<T>
- Favour lazy evaluation over eager evaluation.
- Break large queries up into parts. Key indicators of a large query:
- nesting
- over 10 lines of query expression syntax
- using the
into
keyword
- Name your observables well, i.e. avoid using variable names like
query
,q
,xs
,ys
,subject
etc. - Avoid creating side effects. If you really can't avoid it, don't bury the side effects in callbacks for operators designed to be use functionally such as
Select
orWhere
. Be explicit by using theDo
operator. - Where possible, prefer
Observable.Create
to subjects as a means of defining new Rx sources. - Avoid creating your own implementations of the
IObservable<T>
interface. UseObservable.Create
(or subjects if you really need to). - Avoid creating your own implementations of the
IObserver<T>
interface. Favour using theSubscribe
extension method overloads instead. - The application should define the concurrency model.
- If you need to schedule deferred work, use schedulers
- The
SubscribeOn
andObserveOn
operators should always be right before aSubscribe
method. (So don't sandwich it, e.g.source.SubscribeOn(s).Where(x => x.Foo)
.)