【问题标题】:Why Are AsObservable and AsEnumerable Implemented Differently?为什么 AsObservable 和 AsEnumerable 的实现方式不同?
【发布时间】:2012-03-26 14:22:38
【问题描述】:

Enumerable.AsEnumerable<T>(this IEnumerable<T> source) 的实现只返回source。然而Observable.AsObservable<T>(this IObservable<T> source) 返回一个订阅源的AnonymousObservable<T> 而不是简单地返回源。

我知道这些方法对于在单个查询中更改 monad 非常有用(从 IQueryable => IEnumerable 开始)。那么为什么实现不同呢?

Observable 版本更具防御性,因为您无法将其转换为某些已知类型(如果它最初是作为 Subject<T> 实现的,您将永远无法将其转换为这样的类型)。那么为什么Enumerable 版本不做类似的事情呢?如果我的基础类型是List<T>,但将其公开为IEnumerable<T>AsEnumerable,则可以转换回List<T>

请注意,这不是关于如何公开IEnumerable<T> 而不能够转换到底层的问题,而是为什么EnumerableObservable 之间的实现在语义上是不同的。

【问题讨论】:

标签: c# linq ienumerable system.reactive


【解决方案1】:

文档回答了您的问题,我鼓励您在有此类问题时阅读该文档。

AsEnumerable 的目的是向编译器提示“请停止使用 IQueryable 并开始将其视为内存中的集合”。

正如the documentation 所说:

AsEnumerable<TSource>(IEnumerable<TSource>) 方法除了将源的编译时类型从实现IEnumerable<T> 的类型更改为IEnumerable<T> 本身之外没有任何作用。当序列实现IEnumerable<T> 时,AsEnumerable<TSource>(IEnumerable<TSource>) 可用于在查询实现之间进行选择,但也有一组不同的公共查询方法可用。

如果你想隐藏底层序列的实现,如果你不在乎你正在制作一个可变序列,请使用sequence.Select(x=>x)ToListToArray

AsObservable 的目的是隐藏底层集合的实现。正如the documentation 所说:

Observable.AsObservable<TSource> ... 隐藏可观察序列的身份。

由于这两种方法的目的完全不同,它们的实现也完全不同。

【讨论】:

  • 感谢您的解释。我最近在第 9 频道观看了 Bart De Smet 的视频,他解释了 IQbservable 及其与 IObservable 的关系。从他解释的方式来看,听起来 AsObservable 类似于 AsEnumerable,因为任何可观察的动作都将在本地而不是远程发生。我是否完全误解了这一点(可能......),或者这只是 AsObservable 的另一种用途?
  • 我不知道。我建议问 Bart de Smet 这个问题。
  • 好的,谢谢,可能是个好主意。在询问之前我确实阅读了文档 - 但混淆是由于我之前评论中提到的视频造成的
【解决方案2】:

在从基于表达式树的查询切换到内存查询方面,您对 AsEnumerable 和 AsObservable 之间的关系是正确的。

同时,基于 Subject 暴露一个 Rx 序列非常常见,我们需要一种方法来隐藏它(否则用户可以强制转换为 IObservable 并注入元素)。

很久以前,在 Rx 预发布的历史中,我们确实有一个单独的 Hide 方法,它只是一个 Select(x => x) 别名。我们从不太喜欢它,因此决定有一个地方,我们偏离 LINQ to Objects 的精确镜像,并让 AsObservable 扮演 Hide 的角色,同样基于认为这是它一开始就这样做的用户。

请注意,我们在 IQbservable 上也有一个名为 AsObservable 的扩展方法。它的作用与 AsEnumerable 的作用相同:它提示编译器忘记基于表达式树的查询模式并切换到内存查询。

【讨论】:

  • 感谢巴特查看这个老问题,您的回答提供了一些有趣的信息。
猜你喜欢
  • 2019-09-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-10-19
相关资源
最近更新 更多