Question

Why is IObservable<T> not an implementation of IEnumerable<T> and IQueryable<T>, but I can using LINQ queries? Is IObservable a special type ?

I used to think only Linq query IEnumerable or IQueryable , but it is not. The following code example:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Rx_Test1
{
    public static class IMyClassExtension
    {

        public static MyClass<TResult> Select<TSource, TResult>(this MyClass<TSource> source, Func<TSource, int, TResult> selector)
        {
            return null;
        }

        public static MyClass<TResult> Select<TSource, TResult>(this MyClass<TSource> source, Func<TSource, TResult> selector)
        {
            return null;
        }

    }
    public class MyClass<T>
    {

    }
    class Program
    {
        static void Main(string[] args)
        {
            var myclass = new MyClass<int>();
            var q = from m in myclass 
                    select m;
        }
    }
}
Was it helpful?

Solution

The LINQ query comprehensions work over anything that implements the corresponding Select/Where/etc. methods that the compiler can translate to. It isn't limited to specific interfaces. This is similar to how you can foreach over an object that doesn't implement IEnumerable, but contains a GetEnumerator and MoveNext/Current methods. Effectively LINQ expressions are duck typed by the compiler. This also explains why you can use some LINQ expressions over IObservable but not all (orderby is intentionally excluded).

OTHER TIPS

Why does IObservable not implement IEnumerable or IQuerable

Because IObservable does not necessarily represent a collection - it could be a single object that pushes change events.

But i can using Linq query ?

The Observable class implements Linq-like operators for the IObservable interface. I don't know what it does if the underlying type is not a collection, but my guess is it will either treat it as a single-item collection or throw an exception.

Anything can be made to work with Linq by implementing the appropriate extension methods (Select, SelectMany, Where, ...). This usually only makes sense when the type is a monad, though.

I recommend reading The Marvels of Monads, which has examples of implementing a custom Linq-to-your-type.

In the case of Observable<T>, the Select method gives you back an Observable<T2> where the items have been run through a function. So you can do things like "this observable, but all items +1" via from x in obs select x + 1.

System.Reactive NuGet will allow you to use LINQ to IObservable

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top