Зачем нужен необобщенный IQueryable?

  1. Почему существует неуниверсальный IQueryable, когда есть общий? Не могли бы вы предоставить ему применение?

  2. Разве член ElementType неуниверсального интерфейса IQueryable не является избыточным по той же причине?

Два интерфейса IQueryable были введены значительно позже появления дженериков. Таким образом, наличие как универсальной, так и неуниверсальной версии не выглядит эволюционным прогрессом, как в случае с IEnumerable и его универсальной версией.

Конечно, у Microsoft должны были быть веские причины сохранить оба интерфейса?


person Prakash    schedule 24.01.2015    source источник
comment
Связано: stackoverflow.com/questions /56375/   -  person Chris    schedule 24.01.2015
comment
stackoverflow.com/questions/18535017/queryable-vs-queryablet   -  person The One    schedule 24.01.2015
comment
Посмотрите на это как на сокращение от IQueryable<object> и не более   -  person SimpleVar    schedule 24.01.2015
comment
Я читал серию статей Мэтта Уоррена о создании провайдера LINQ и не совсем понимаю, что он имеет в виду под выражением сценарии создания динамических запросов, когда говорит: «Общий IQueryable‹T› — это тот, который вы используете чаще всего». в сигнатурах методов и т.п. Неуниверсальные IQueryable существуют в первую очередь для того, чтобы предоставить вам слабо типизированную точку входа, прежде всего, для сценариев построения динамических запросов.   -  person Prakash    schedule 24.01.2015
comment
Я категорически не согласен с комментарием @YoryeNathan. Смотрите мой ответ.   -  person Chad Carisch    schedule 09.02.2015


Ответы (1)


Основная цель этого интерфейса — разрешить доступ к ElementType, Expression и Provider без необходимости знать универсальный тип.

Это довольно распространенная практика для Microsoft при написании универсальных типов. List<T> наследуется от IList<T>, который наследуется от IList.

Другими словами, вы хотите предоставить любое свойство, которое не требует универсального типа, неуниверсальным способом. В случае IQueryable<T> свойства не раскрываются. Однако общий тип T допускает строго типизированные методы расширения, которые можно найти в System.Linq.Queryable.

Обратите внимание на следующее:

void Main()
{
    var lst = new List<string>();
    lst.Add("test1");
    lst.Add("test2");
    lst.Add("test3");

    IQueryable<string> q = lst.AsQueryable();

    PrintQueryInfo(  q.Where(x=>x.Contains('1')));

}

public void PrintQueryInfo(IQueryable q){
    Console.WriteLine(q.Expression.ToString());
}

Выход:

System.Collections.Generic.List`1[System.String].Where(x => x.Contains(1))

Также стоит отметить, что приведенный выше пример также может быть выполнен с помощью универсального метода. Но это не всегда возможно или практично.

public void PrintQueryInfo<T>(IQueryable<T> q){
    Console.WriteLine(q.Expression.ToString());
}
person Chad Carisch    schedule 09.02.2015