Как работает Queryable.OfType?
-
10-07-2019 - |
Вопрос
Важно . Вопрос не в том, что &, что делает 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 }));
}
Итак, давайте посмотрим, правильно ли я понял:
<Ол>null
как Теперь эффект этого метода состоит в том, чтобы возвращать выражение, которое сообщает провайдеру, что нужно не возвращать возвращаемые значения, если тип не равен TResult или одному из его подтипов. Но я не вижу, как вышеперечисленные шаги действительно достигают этого. Кажется, что создается выражение, представляющее метод, который возвращает IQueryable & Lt; TResult & Gt;, и тело этого метода просто превращается во все исходное выражение, даже не смотря на тип. Просто ожидалось, что провайдер IQueryable просто молча не вернет никаких записей не выбранного типа?
Так что вышеперечисленные шаги в некоторой степени некорректны, или я просто не вижу, как они приводят к поведению, наблюдаемому во время выполнения?
Решение
Он не передает null
как метод - он передает его как " целевое выражение " ;, т. е. для чего он вызывает метод. Это ноль, потому что OfType
- статический метод, поэтому ему не нужна цель.
Смысл вызова MakeGenericMethod
в том, что GetCurrentMethod()
возвращает открытую версию, т.е. OfType<>
вместо OfType<YourType>
.
Queryable.OfType
сам по себе не предназначен , чтобы содержать какую-либо логику для пропуска возврата любых значений. Это зависит от поставщика LINQ. Смысл Queryable
состоит в том, чтобы создать дерево выражений, включающее в себя вызов <=>, чтобы когда поставщику LINQ в конечном итоге пришлось преобразовать его в его собственный формат (например, SQL), он знал, что был вызван <=>. р>
Так работает <=> в целом - в основном это позволяет провайдеру видеть все выражение запроса в виде дерева выражений. Это все, что он должен делать - когда провайдера просят перевести это в реальный код, это , где происходит волшебство.
<=> не мог выполнить всю работу сам - он понятия не имеет, какое хранилище данных представляет поставщик. Как он мог придумать семантику <=>, не зная, было ли хранилище данных SQL, LDAP или что-то еще? Я согласен, что требуется время, чтобы обдумать:)