Принцип, которому я следую, тот, который я прочитал некоторое время назад:
"Употребляй самое простое и выставляй
самый сложный "
(Я уверен, что это действительно распространенное явление, и я неправильно цитирую его, если кто-то может знать источник, можете ли вы оставить комментарий или отредактировать, пожалуйста ...)
(Отредактировано, чтобы добавить - ну, вот я через пару недель, и я только что натолкнулся на эту цитату в совершенно ином контексте, похоже, она началась как Принцип устойчивости или Постель Закон -
Будьте консервативны в том, что вы делаете; будь либеральным в том, что ты принимаешь от других.
Первоначальное определение предназначено для сетевого взаимодействия через Интернет, но я уверен, что я видел его многоцелевым для определения классовых контрактов в ОО.)
По сути, если вы определяете метод для внешнего потребления, тогда параметры должны быть самым базовым типом, который дает вам требуемую функциональность - в случае вашего примера это может означать использование IEnumerable вместо IList. Это дает клиентскому коду максимальную гибкость по сравнению с тем, что он может передать. С другой стороны, если вы выставляете свойство для внешнего потребления, то делайте это с наиболее сложным типом (IList или ICollection вместо IEnumerable), так как это дает клиенту больше всего возможностей. гибкость в том, как они используют объект.
Я нахожу разговор между мной и DrJokepu в комментариях увлекательным, но я также ценю, что это не должен быть дискуссионный форум, поэтому я отредактирую свой ответ, чтобы дополнительно обрисовать причины своего выбора тенденция и предложить вам выставить его как IList (ну, на самом деле, список, как вы увидите). Скажем, это класс, о котором мы говорим:
public class Example
{
private List<int> _internal = new List<int>();
public /*To be decided*/ External
{
get { return _internal; }
}
}
Итак, давайте сначала предположим, что мы выставляем External как IEnumerable. Причины, которые я видел для этого в других ответах и комментариях, в настоящее время:
- IEnumerable доступен только для чтения
- IEnumerable является стандартом по умолчанию
- Это уменьшает сцепление, так что вы можете изменить реализацию
- Вы не раскрываете детали реализации
Хотя IEnumerable предоставляет только функции только для чтения, которые не делают его доступным только для чтения. Реальный тип, который вы возвращаете, легко узнать по рефлексии или просто приостановив отладчик и просмотрев, так что тривиально вернуть его обратно в List <>, то же самое относится к примеру FileStream в комментариях ниже. Если вы пытаетесь защитить участника, то притворяться, что это что-то другое, не способ сделать это.
Я не верю, что это стандарт де-факто. Я не могу найти никакого кода в библиотеке .NET 3.5, где у Microsoft была возможность вернуть конкретную коллекцию и вместо нее вернуть интерфейс. IEnumerable является более распространенным в 3.5 благодаря LINQ, но это потому, что они не могут предоставить более производный тип, а не потому, что они не хотят.
Теперь, уменьшая связь, с которой я согласен - до некоторой степени - в основном, этот аргумент, по-видимому, заключается в том, что вы говорите клиенту, что в то время, как возвращаемый вами объект представляет собой , список, который я хочу, чтобы вы рассматривали как IEnumerable на тот случай, если вы решите изменить внутренний код позже. Игнорирование проблем с этим и факта, что реальный тип все равно выставлен, оставляет вопрос «зачем останавливаться на IEnumerable?» если вы вернете его как тип объекта, у вас будет полная свобода изменить реализацию на что угодно! Это означает, что вы должны были принять решение о том, какой функциональности требует клиентский код, поэтому либо вы пишете клиентский код, либо решение основано на произвольных метриках.
Наконец, как уже говорилось ранее, вы можете предположить, что детали реализации всегда выставляются в .NET, особенно если вы публично выставляете объект.
Итак, после этой длинной диатрибы остался один вопрос - зачем выставлять его в виде списка <>? А почему бы не? Вы ничего не получили, выставив его как IEnumerable, так зачем же искусственно ограничивать способность клиентского кода работать с объектом? Представьте себе, если бы Microsoft решила, что коллекция Controls элемента управления Winforms должна отображаться как IEnumerable вместо ControlCollection - вы больше не сможете передавать его методам, которые требуют IList, работать с элементами с произвольным индексом или посмотреть, если он содержит определенный элемент управления, если вы не разыгрываете его. Microsoft на самом деле ничего не получила бы, и это доставило бы вам неудобства.