Зачем возвращать интерфейс коллекции, а не конкретный тип?
Я заметил в коде других людей, что методы, возвращающие общие коллекции, почти всегда возвращают интерфейс (например, IEnumerable<T>
или IList<T>
), а не конкретную реализацию.
У меня есть два связанных вопроса. Во-первых, почему (если вообще) считается лучшим вернуть интерфейс? Во-вторых, существует ли интерфейс коллекции, который включает метод Sort (как это делает List<T>
)?
Ответы
Ответ 1
Из С# - Список или IList
Если вы подвергаете свой класс библиотеку, которую другие будут использовать, вы как правило, хотят интерфейсы, а не конкретные Реализации. Это поможет, если вы принять решение об изменении ваш класс позже использовать другой конкретный класс. В этом случае пользователю вашей библиотеки не потребуется обновить свой код, так как интерфейс не изменяется.
Если вы просто используете его внутри, вам может не все равно, и использование Список может быть в порядке.
Ответ 2
Для первого вопроса: если вы вернете интерфейс, вы сохраните большую гибкость. Вы можете позже изменить реализацию, чтобы вернуть другой конкретный тип. С другой стороны, это, очевидно, дает абоненту меньше информации, поэтому они не могут выполнять определенные операции. (например, если вы вернете List<T>
, вызывающий может использовать ConvertAll и т.д., который они не могут, если вы только объявляете, что возвращаете IList<T>
.) В некоторых ситуациях стоит указать конкретный тип; Обычно я предпочитаю, по крайней мере, начинать с интерфейсов, и переходить только к конкретному типу в качестве возвращаемого типа, если обнаруживаю, что часто хочу использовать дополнительные доступные методы.
Во-вторых, никакие стандартные интерфейсы сбора данных не имеют метода Sort
. С другой стороны, вы можете написать метод расширения для сортировки любых IList<T>
. Лично я обычно предпочитаю методы LINQ OrderBy
, OrderByDescending
, ThenBy
и ThenByDescending
... хотя они возвращают новую последовательность, а не сортировку на месте.
Ответ 3
Мы используем интерфейсы, чтобы предоставить нам большую гибкость в нашей реализации. Поэтому, если у вашего метода есть возвращаемый тип IEnumerable, вы можете изменить объект, который он возвращает из списка в массив, не изменяя объекты, зависящие от метода.
Это также выразительно: если вы возвращаете IEnumerable, когда объект используется, он очищается от кодера, и мы заботимся только о том, чтобы он представлял собой какую-то коллекцию, а не конкретный тип
Ответ 4
Я не могу говорить для всех, но, как правило, я делаю это только потому, что мне нравится только возвращать то, что мне нужно. Почему вы возвращаете полностью раздутую коллекцию, когда все, что вам нужно, - это перечислимая коллекция, которую можно повторить.
Что касается другой части вашего вопроса, вы всегда можете использовать IList, а затем использовать LINQ для сортировки:
list.OrderBy(a=>a.Id);