Вопрос

Важно . Вопрос не в том, что &, что делает Queryable.OfType делать , а в том, что это &, как код, который я там вижу, выполняет это? Quot &;

Размышляя о Queryable.OfType, я вижу (после некоторой очистки):

    public static IQueryable<TResult> OfType<TResult>(this IQueryable source)
    {
        return (IQueryable<TResult>)source.Provider.CreateQuery(
            Expression.Call(
                null, 
                ((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(
                    new Type[] { typeof(TResult) }) ,
                    new Expression[] { source.Expression }));
    }

Итак, давайте посмотрим, правильно ли я понял:

<Ол>
  • Используйте отражение, чтобы получить ссылку на текущий метод (OfType).
  • Создайте новый метод, который точно такой же, с помощью MakeGenericMethod, чтобы изменить параметр типа текущего метода, в общем, на то же самое.
  • Аргументом для этого нового метода будет не source, а source.Expression. Что не является IQueryable, но мы передадим все это Expression.Call, так что все в порядке.
  • Вызовите Expression.Call, передав null как метод (странный?) instance и клонированный метод в качестве аргументов.
  • Передайте этот результат в CreateQuery и приведите результат, который кажется самой разумной частью всего этого.
  • Теперь эффект этого метода состоит в том, чтобы возвращать выражение, которое сообщает провайдеру, что нужно не возвращать возвращаемые значения, если тип не равен TResult или одному из его подтипов. Но я не вижу, как вышеперечисленные шаги действительно достигают этого. Кажется, что создается выражение, представляющее метод, который возвращает IQueryable & Lt; TResult & Gt;, и тело этого метода просто превращается во все исходное выражение, даже не смотря на тип. Просто ожидалось, что провайдер IQueryable просто молча не вернет никаких записей не выбранного типа?

    Так что вышеперечисленные шаги в некоторой степени некорректны, или я просто не вижу, как они приводят к поведению, наблюдаемому во время выполнения?

    Это было полезно?

    Решение

    Он не передает null как метод - он передает его как " целевое выражение " ;, т. е. для чего он вызывает метод. Это ноль, потому что OfType - статический метод, поэтому ему не нужна цель.

    Смысл вызова MakeGenericMethod в том, что GetCurrentMethod() возвращает открытую версию, т.е. OfType<> вместо OfType<YourType>.

    Queryable.OfType сам по себе не предназначен , чтобы содержать какую-либо логику для пропуска возврата любых значений. Это зависит от поставщика LINQ. Смысл Queryable состоит в том, чтобы создать дерево выражений, включающее в себя вызов <=>, чтобы когда поставщику LINQ в конечном итоге пришлось преобразовать его в его собственный формат (например, SQL), он знал, что был вызван <=>.

    Так работает <=> в целом - в основном это позволяет провайдеру видеть все выражение запроса в виде дерева выражений. Это все, что он должен делать - когда провайдера просят перевести это в реальный код, это , где происходит волшебство.

    <=> не мог выполнить всю работу сам - он понятия не имеет, какое хранилище данных представляет поставщик. Как он мог придумать семантику <=>, не зная, было ли хранилище данных SQL, LDAP или что-то еще? Я согласен, что требуется время, чтобы обдумать:)

    Лицензировано под: CC-BY-SA с атрибуция
    Не связан с StackOverflow
    scroll top