Какой интерфейс должен вернуть мой сервис? IQueryable, IList, IEnumerable? - PullRequest
9 голосов
/ 25 марта 2009

Представьте, что у меня есть слой SearchService, в котором есть метод для поиска всех автомобилей, начинающихся с определенной строки;

public static class Searcher{
    public IAnInterface<Car> CarsStartingWith(string startWith){
        //magic
    }
}

Какой интерфейс должен использовать мой сервис?
IQueryable может сделать хороший интерфейс в остальной части моего приложения.
У IEnumerable есть ленивый аспект.
IList просто самый практичный.

Я бы хотел, чтобы все мои службы возвращали один и тот же интерфейс для согласованности, что делает все это намного проще.
ICollection может быть и вариант, но он так мало предлагает ...

Ответы [ 7 ]

3 голосов
/ 25 марта 2009

Мое эмпирическое правило таково:

Если когда-нибудь появится шанс, что я смогу взять основной алгоритм подпрограммы и реорганизовать его так, чтобы я мог использовать возвращаемую доходность, я пойду с IEnumerable .

Например, если моя текущая реализация использует массив или List для внутреннего использования, но я знаю, что, по крайней мере, теоретически, я могу захотеть и иметь возможность переработать его внутренне для выполнения отложенной оценки, я вернусь IEnumerable .

Я обнаружил, что выгоды от возвращения IEnumerable определенно стоят хлопот с его использованием.

Однако, если алгоритму по своей природе потребуется полностью оценить результаты перед возвратом (редко, но это случается), я пойду с IList . В основном, если я уже вычисляю это, я верну это. IList реализует IEnumerable , поэтому все связанные с LINQ варианты использования по-прежнему работают, но вы теряете ленивую оценку. Если я уже вынужден оценивать заранее, это не проблема.

Я редко возвращаю IQueryable. Единственный раз, когда я бы использовал этот интерфейс, это если я непосредственно создаю запрашиваемый слой доступа к данным или что-то подобное. Затраты на его использование в большинстве случаев не стоят выигрыша.

Однако, если ваша цель - всегда использовать один интерфейс (я не обязательно согласен с этой целью), я бы придерживался IEnumerable .

3 голосов
/ 25 марта 2009

Я бы выбрал IEnumerable, потому что он занимает более центральное место в структуре, обеспечивая универсальность для тех, кто в ней нуждается, а также обеспечивает знакомство тем, кто еще не застрял в таких вещах, как LINQ.

2 голосов
/ 25 марта 2009

Всегда используйте IEnumerable, если у вас нет серьезных причин не делать этого. Затем вы можете реализовать метод получения с помощью yield return.

IQueryable - это совершенно другой котелок с рыбой. Не то, что вы бы случайно использовали как альтернативу типичному контейнеру в памяти.

В остальном, между IEnumerable и остальными есть существенная разница: это только для чтения.

2 голосов
/ 25 марта 2009

Если вы хотите, чтобы все ваши сервисы возвращали один и тот же интерфейс, я бы, вероятно, выбрал IEnumerable<>.

Вашим абонентам будет достаточно легко преобразовать в IQueryable или создать List, если необходимо:

IEnumerable<Car> cars = Searcher.CarsStartingWith("L");
var carsList = cars.ToList();
var queryableCars = cars.AsQueryable();
2 голосов
/ 25 марта 2009

Краткий ответ: зависит.

Более длинный ответ: верните самый богатый тип, который понадобится вашему клиентскому коду. IList работает в большинстве случаев, если вам не нужна ленивая загрузка. Вы все еще можете использовать Linq для запроса к IList или IEnumerable. Если требуется отложенная загрузка, используйте IEnumerable или IQueryable.

Примечание: возвращение одного и того же интерфейса для всех сервисов может показаться благородной целью, но с учетом разных моделей использования клиентов вы можете захотеть вернуть разные интерфейсы.

2 голосов
/ 25 марта 2009

IQueryable будет довольно жестким требованием - вы не сможете, например, вернуть массив.

Обычно для меня выбор между IEnumerable или IList обычно заканчивается тем, что легче реализовать в стандартном случае.

0 голосов
/ 14 марта 2013

Если вы используете IQueryable в качестве возвращаемого типа, у вас есть сервисный уровень с неплотной абстракцией.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...