2012-03-26 16 views
8

La implementación de Enumerable.AsEnumerable<T>(this IEnumerable<T> source) simplemente devuelve source. Sin embargo, Observable.AsObservable<T>(this IObservable<T> source) devuelve un AnonymousObservable<T> suscribirse a la fuente en lugar de simplemente devolver la fuente.¿Por qué se implementan AsObservable y AsEnumerable de forma diferente?

Entiendo que estos métodos son realmente útiles para cambiar la mónada en una sola consulta (yendo de IQueryable => IEnumerable). Entonces, ¿por qué difieren las implementaciones?

La versión Observable es más defensiva, en el sentido de que no se puede convertir a algún tipo conocido (si se implementara originalmente como Subject<T> nunca sería capaz de lanzarlo como tal). Entonces, ¿por qué la versión Enumerable no hace algo similar? Si mi tipo subyacente es List<T> pero lo expongo como IEnumerable<T> a través de AsEnumerable, será posible volver a un List<T>.

Tenga en cuenta que esto no es una cuestión de cómo exponer IEnumerable<T> sin ser capaz de lanzar al subyacente, pero ¿por qué las implementaciones entre Enumerable y Observable son semánticamente diferente.

Respuesta

13

Su pregunta es respondida por la documentación, que le animo a leer cuando tenga dichas preguntas.

El objetivo de AsEnumerable es hacer una alusión al compilador "deje de utilizar IQueryable y comience a tratar esto como una recopilación en memoria".

Como the documentation estados:

El método AsEnumerable<TSource>(IEnumerable<TSource>) no tiene otro efecto que para cambiar el tipo de tiempo de compilación de la fuente de un tipo que implementa IEnumerable<T>-IEnumerable<T> sí mismo. AsEnumerable<TSource>(IEnumerable<TSource>) se puede utilizar para elegir entre implementaciones de consulta cuando una secuencia implementa IEnumerable<T> pero también tiene un conjunto diferente de métodos de consulta públicos disponibles.

Si desea ocultar la ejecución de una secuencia subyacente, utilice sequence.Select(x=>x) o ToList o ToArray si no importa que usted está haciendo una secuencia mutable.

El objetivo de AsObservable es ocultar la implementación de la colección subyacente. Como the documentation dice:

Observable.AsObservable<TSource> ... Oculta la identidad de una secuencia observable.

Dado que los dos métodos tienen propósitos completamente diferentes, tienen implementaciones completamente diferentes.

+0

Gracias por la explicación. Recientemente vi un video en el Canal 9 con Bart De Smet, donde explicó IQbservable y su relación con IObservable. Por la forma en que lo explicó, parecía que AsObservable era el análogo de AsEnumerable en el sentido de que cualquier acción observable ocurriría localmente en vez de remotamente. ¿Entendí totalmente esto (probablemente ...) o simplemente es otro uso de AsObservable? – RichK

+0

No lo sé. Recomiendo hacerle esta pregunta a Bart de Smet. –

+0

Bien gracias, probablemente sea una buena idea. Leí la documentación antes de preguntar, pero la confusión fue como resultado del video mencionado en mi comentario anterior – RichK

9

Tiene razón acerca de la relación entre AsEnumerable y AsObservable con respecto al aspecto de pasar de las consultas basadas en el árbol de expresiones a las consultas en memoria.

Al mismo tiempo, la exposición de una secuencia Rx basado en un sujeto <T> es muy común, y que necesitaba una manera de esconderlo (de lo contrario el usuario podría emitir a IObservable <T> e inyectar elementos).

Hace mucho tiempo en la historia de las versiones previas de Rx, teníamos un método Hide por separado, que era simplemente un alias Select (x = > x). Nunca nos gustó y decidimos tener un lugar en el que nos desviamos del espejo preciso de LINQ to Objects, e hicimos que AsObservable desempeñara el papel de Hide, también basado en usuarios que creían que esto era lo que hacía para empezar.

Sin embargo, tenga en cuenta que tenemos un método de extensión llamado AsObservable en IQbservable <T> también. Eso hace simplemente lo que AsEnumerable también: actúa como una sugerencia para que el compilador olvide el modo de consulta basado en el árbol de expresiones y cambie a las consultas en la memoria.

+0

Gracias por verificar esta vieja pregunta, Bart, su respuesta proporciona información interesante. – RichK

Cuestiones relacionadas