Почему синтаксис linq работает через интерфейс IQueryable в Rx Framework - PullRequest
0 голосов
/ 21 июня 2010

Я начал просматривать реактивные рамки. Очень хорошие вещи. Но, глядя на примеры кода, я запутался. Синтаксис linq работает с IQueryable. Я думал, что linq работает только с IEnumerable. На чем основывается компилятор C #, это linq для преобразования методов расширения Требуется ли набор методов с определенным интерфейсом?

1 Ответ

5 голосов
/ 21 июня 2010

Не совсем. Это просто синтаксический перевод. Например, компилятор переведет это:

var query = from item in source
            select item.Property;

в

var query = source.Select(item => item.Property);

Он делает это, ничего не зная о методе Select. Он просто выполняет перевод, а затем пытается скомпилировать переведенный код.

Все переводы тщательно документированы в разделе 7.16 спецификации C # 4 (и, конечно, эквивалент для более ранних выпусков).

В случае Rx он вызывает расширения на IObservable<T> и IQbservable<T>. В случае параллельных расширений он вызывает методы расширения для 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);
        }
    }
}

Запрос переводится как:

WeirdQueryExpression.Where(x => x * 3)
                    .Select(x => x.Length > 10);

... который является вызовом статического метода, который возвращает WeirdQueryExpression, за которым следует доступ к свойству Where, которое возвращает Func<Func<string, bool>, string>. Затем мы вызываем этого делегата (передавая другого делегата) и присваиваем результат query.

фанк, да?

...