@Venesuella
BlackJack и ...

Почему IQueryable когда IEnumerable?

Здравствуйте! Подскажите, в одном из статей наткнулся на пример
public IEnumerable<SomeValue> SomeMethod()
{
 return db.SomeValue.Select(item=>item);
}


и в примере сказано что возвращается IQuerable, меня это смутило, почему IQuerable, когда возвращаемый тип IEnumerable, разве IQuerable не приведется к IEnumerable?
  • Вопрос задан
  • 879 просмотров
Пригласить эксперта
Ответы на вопрос 2
Строго говоря Select это метод расширения (extension method) и в зависимости от объекта может вернуть и IEnumerable и IQueryable.

IQuerable "является" (наследует) IEnumerable поэтому в твоем примере приведения как такового не происходит, но вызывающий код не может быть уверен, что ему вернули именно IQuerable (db.SomeValue.ToList().Select(item=>item); и все меняется ).

Возвращать базовый интерфейс можно (надо только смотреть почему и зачем) и в данном случае, в вызывающем коде можно выполнить приведение к IQueryable. Но в общем случае не каждый IEnumerable можно привести IQueryable.

Интерфейс IEnumerable обычно реализуют коллекции, которые хранят уже полученные объекты, тогда как IQueryable объекты, которые инкапсулируют запросы. В вызывающем коде к IQueryable ты как бы можешь добавить условия (Skip(), Take(), Where()) и реальный запрос на сервер будет с учетом этих условий. Но если ты уже выполнил запрос (ToList()) тогда все остальные операции будут на клиенте.

Представь таблицу с миллионом записей и подумай в чем разница:
db.SomeValue.Select(item=>item).Take(100);
и
db.SomeValue.Select(item=>item).ToList().Take(100);
Ответ написан
@ar4ebaldello
IQueryable наследует IEnumerable. Т.е. в этом примере получаем приведение ссылки вверх по иерархии. Этот метод вернет нам не IQueryable и даже не IEnumerable, а объект какого-то конечного класса, что реализует эти интерфейсы.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы