【问题标题】:IObservable<T> using linq queryIObservable<T> 使用 linq 查询
【发布时间】:2014-02-21 15:32:14
【问题描述】:

为什么IObservable&lt;T&gt; 不是IEnumerable&lt;T&gt;IQueryable&lt;T&gt; 的实现,但我可以使用LINQ 查询? IObservable 是不是特殊类型?

我以前认为只有 Linq 查询 IEnumerable 或 IQueryable ,但事实并非如此。以下代码示例:

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;
        }
    }
}

【问题讨论】:

  • 实现IObservable的对象也可以实现其他接口,如IQuerable。你在说哪个 conrete 对象?

标签: c# .net linq system.reactive


【解决方案1】:

LINQ 查询理解适用于实现相应 Select/Where/etc 的任何内容。编译器可以翻译成的方法。它不限于特定的接口。这类似于您如何遍历未实现 IEnumerable 但包含 GetEnumerator 和 MoveNext/Current 方法的对象。实际上 LINQ 表达式是由编译器键入的鸭子类型。这也解释了为什么您可以在 IObservable 上使用一些 LINQ 表达式,但不能全部使用(有意排除 orderby)。

【讨论】:

    【解决方案2】:

    为什么IObservable 没有实现IEnumerableIQuerable

    因为IObservable 不一定 代表一个集合 - 它可能是推动更改事件的单个对象。

    但我可以使用 Linq 查询?

    Observable 类为IObservable 接口实现了类似 Linq 的运算符。如果底层类型不是集合,我不知道它会做什么,但我猜它要么将其视为单项集合,要么抛出异常。

    【讨论】:

    • IObservable&lt;&gt; 绝对代表一个集合。它与IEnumerable&lt;&gt; 100% 相似。所以要么他们都代表一个集合,要么他们都不代表。
    • @Enigmativity 100% 类似?如何? documentation for IObservable&lt;T&gt; 没有提及收藏。事实上,example 并没有使用集合作为可观察类型。 System.Reactive.Linq.Observable扩展方法使它看起来IEnumerable&lt;T&gt;,但它们是完全独立的接口。
    • 它们不一定是相似的,但从 lambda 演算的角度来看它们是对偶的。就像 x/y = z 和 x = zy 一样,我翻转输入和输出,IEnumerable 等于 IObservable。好消息是您不必了解 lambda 演算即可利用/使用/爱 Rx。
    • @DStanley - 正是吉姆所说的。作为数学对偶意味着它们实际上是同一件事。在我看来,考虑它们的最佳方式是 IEnumerable&lt;&gt; 是一个瞬时集合,IObservable&lt;&gt; 是一个随时间推移的集合。
    • @DStanley - 看看这个来自 Rx 创作者的视频 - channel9.msdn.com/Shows/Going+Deep/…
    【解决方案3】:

    通过实现适当的扩展方法(SelectSelectManyWhere、...),任何东西都可以与 Linq 一起使用。不过,这通常仅在类型为 monad 时才有意义。

    我建议阅读The Marvels of Monads,其中包含实现自定义 Linq-to-your-type 的示例。

    Observable&lt;T&gt; 的情况下,Select 方法会返回一个Observable&lt;T2&gt;,其中项目已通过函数运行。因此,您可以通过from x in obs select x + 1 执行“这个可观察的,但所有项目 +1”之类的操作。

    【讨论】:

      【解决方案4】:

      System.Reactive NuGet 将允许您使用 LINQ to IObservable

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多