16

你如何确定一个方法是否应该返回IEnumerable<T>or IObservable<T>

为什么我会选择一种范式而不是另一种?

4

4 回答 4

26

类型

  • IEnumerable<T>
    • 您反复从T's序列中“拉”
  • IObservable<T>
    • 一系列T' 正被“推”向你

为什么我会选择一种范式而不是另一种?

您通常不会“选择”一种范式而不是另一种范式。通常,一个自然而然地成为正确的选择,而另一个则没有任何意义。

例子

考虑以下示例:

  • 一个巨大的 CSV 文本文件的每一行都有一个项目,您希望一次处理一个项目,而不是一次将整个文件加载到内存中:IEnumerable<List<string>>

  • 您正在运行 HTTP Web 服务器:IObservable<WebRequest>

  • 您想以广度优先的方式获取树数据结构的节点:IEnumerable<Node>

  • 您正在响应用户界面按钮点击:IObservable<Click>

在这些示例中的每一个(尤其是IObservable<T>案例)中,使用其他类型是没有意义的。

但是如果我想使用“其他”类型怎么办......

IObservable<T>IEnumerable<T>

如果某事物自然是 anIObservable<T>但您想将其视为 an 来处理,则IEnumerable<T>可以使用以下方法执行此操作:

IEnumerable<T> Observable.ToEnumerable(this IObservable<T>)
  • 当 aT被 推“推”时IObservable<T>,它会被发送到队列中。
  • 当您尝试从 中“拉” aTIEnumerable<T>,它会阻塞,直到队列不为空,然后出队。

IEnumerable<T>IObservable<T>

如果某事物自然是 anIEnumerable<T>但您想将其视为 an 来处理,则IObservable<T>可以使用以下方法执行此操作:

IObservable<T> Observable.ToObservable(this IEnumerable<T>)
  • .NET 线程池中的线程将反复尝试TIEnumerable<T>.
  • 每次它“拉” aT时,它都会通过IObservable<T>.
于 2013-06-13T20:27:58.390 回答
8

如果IObservable<T>您想在方便时将数据送给方法的调用者,请使用。您可以通过调用该注册兴趣来执行此操作。OnNext()ObserversSubscribe()

如果IEnumerable<T>您希望方法的调用者在方便时提取数据,请使用。他们通过调用来获取一个并调用和(编译为此)来做到这一点。GetEnumerator()IEnumeratorMoveNext()Currentforeach

更新:也许最好举一些例子:

返回银行货币价格的函数是IObservable<T>. 这里的信息是时间关键的。作为此数据的服务器,您需要尽快将其发送到客户端。客户端不知道该数据何时准备就绪。所以你把它推给他们。

返回特定金融工具的有效交易日并用于填充日历控件上的停电日的函数是 IEnumerable 的理想选择。此数据很少更改,并且客户端(设置控件)更喜欢以它指定的速度使用它。

于 2013-06-13T09:13:22.623 回答
4

IObservable<T>是一个专用接口,可用于 pub/sub 和各种其他模式。你会知道什么时候需要返回一个IObservable<T>,所以如果没有特定的需要,那么返回IEnumerable<T>

更新评论中的问题

基本上,IObservable<>使用“推”机制,而 IEnumerable<> 使用“拉”机制。如果您只想获取不需要通知订阅者更改(推送)的数据列表,那么您可以使用IEnumerable. 如果订阅者(窗口、控件、其他客户端程序/例程等)需要知道数据何时更改,则使用IObservable<>. 一个示例是IObservable用于从子线程更新 Windows 程序中的主 UI 线程(通常,如果没有花哨的步法,这将无法完成。阅读 .NET Reactive Extensions (Rx.NET)。

于 2013-06-13T08:20:01.850 回答
1

用来IEnumerable<T>表示列表,IObservable<T>用来表示事件。十分简单。

于 2013-06-14T05:47:30.290 回答