为什么linq语法在Rx Framework中的IQueryable接口上工作

Sil*_*viu 0 system.reactive c#-4.0

我已经开始研究反应框架了.非常好的东西.但是在查看代码示例时,它让我很困惑.linq语法适用于IQueryable.我认为linq只适用于IEnumerable.关于C#编译器将它的linq基于扩展方法转换的内容是什么?它是否需要一组具有特定接口的方法?

Jon*_*eet 5

不完全的.这只是一个句法翻译.例如,编译器将翻译此:

var query = from item in source
            select item.Property;
Run Code Online (Sandbox Code Playgroud)

var query = source.Select(item => item.Property);
Run Code Online (Sandbox Code Playgroud)

它在不了解该Select方法的情况下做到了这一点.它只是进行翻译,然后尝试编译已翻译的代码.

所有翻译都在C#4规范的第7.16节(以及当前早期版本的等效文件)中进行了详细记录.

在Rx的情况下,它会调用扩展的IObservable<T>IQbservable<T>.在Parallel Extensions的情况下,它调用扩展方法ParallelQuery<T>.

你可以用它来做一些疯狂的事情 - 我有一篇博文,里面举了几个例子.这是另一个奇怪的:

using System;
using System.Linq;

namespace CornerCases
{
    class WeirdQueryExpression
    {
        static WeirdQueryExpression Where(Func<int, int> projection)
        {
            return new WeirdQueryExpression { Select = ignored => "result!" };
        }

        Func<Func<string, bool>, string> Select { get; set; }

        static void Main()
        {
            string query = from x in WeirdQueryExpression
                           where x * 3
                           select x.Length > 10;

            Console.WriteLine(query);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

该查询转换为:

WeirdQueryExpression.Where(x => x * 3)
                    .Select(x => x.Length > 10);
Run Code Online (Sandbox Code Playgroud)

...这是对静态方法的调用,它返回一个WeirdQueryExpression,然后访问Where返回a 的属性Func<Func<string, bool>, string>.然后我们调用该委托(传入另一个委托)并将结果分配给query.

时髦,是吧?