Предположим, у меня есть метод
public List<User> GetBatchOfUsers(IEnumerable<int> userIDs)
{
List<User> users = new List<User>();
// some database stuff
return users;
}
Я прочитал, что было бы лучше вернуть интерфейс (либо IList
или IEnumerable
), а не возвращать List
. Некоторые аргументы, которые я слышал для этого, заключаются в том, что он скрывает данные и дает разработчику API возможность изменить внутреннее представление данных на более позднем этапе.
Моя проблема с возвратом IEnumerable
- это потеря функциональности, такой как произвольный доступ и Count
собственность.
Я знаю, что принятие IEnumerable
в качестве параметра имеет смысл, поскольку оно дает потребителю наилучшую гибкость при отправке данных моему методу, минимальный набор требований для работы метода.
Какова наилучшая практика для типа возврата?
c#
interfaces
class
Мэтью
источник
источник
Ответы:
Вообще говоря, вы можете начать с интерфейсов и переходить к конкретному типу в качестве возвращаемого, только если обнаружите, что вы используете дополнительные методы чаще, чем ожидалось.
Что ж, если вы вернете интерфейс, вы сохраните большую гибкость. Вы можете изменить реализацию позже, чтобы получить другой конкретный тип. С другой стороны, это, очевидно, дает вызывающим абонентам меньше информации, поэтому они могут не иметь возможности выполнять определенные операции. (Например: если вы вернетесь
List<T>
, вызывающая сторона может использовать ConvertAll и т. Д., Чего они не смогут, если вы только объявите, что возвращаетеIList<T>
.) В некоторых ситуациях стоит указать конкретный тип.Что касается метода Count или Sort, для этого нет стандартных интерфейсов сбора. Однако вы можете написать метод расширения для сортировки или подсчета любого IList.
источник
Если вам нужна ваша коллекция,
Count
вы можете использовать ееICollection<T>
, что является достаточно общим.источник
Вы возвращаете то, что разумно для метода, который вы определяете. Что вы делаете, возвращая серию элементов (основное внимание уделяется элементам), или это возвращает коллекцию элементов (основное внимание уделяется коллекции в целом)? Стоит ли допускать отклонения в реализации коллекции? Если никогда не будет смысла использовать генератор или
HashSet
просто использоватьList
.источник
Специфично для примера метода: вы правы, возвращение
IEnmuerable<T>
означало бы, что вы потеряете функциональностьCount
и индексацию (хотя вы можете использовать методы LINQCount()
иElementAt()
, которые реализуются эффективно, если тип, который они используют на самом деле, реализуетIList<T>
).Если вы вернетесь
IList<T>
, вы потеряете некоторую функциональность, но выигрыш в общем, вероятно, того стоит.Но даже лучше было бы что-то среднее между
IEnumerable<T>
иIList<T>
, потому что для потребителя, скорее всего, не имеет смысла мутировать возвращенную коллекцию, но для него имеет смысл использоватьCount
или индексировать.В .Net 4.5, есть такой интерфейс:
IReadOnlyList<T>
.источник
IReadOnlyList
звучит хорошо, когда я могу получить VS2013, спасибо!