Уровень доступа к данным: разоблачающий список <>: плохая идея? - PullRequest
3 голосов
/ 14 октября 2008

В настоящее время я кодирую простой уровень доступа к данным, и мне было интересно, какой тип я должен предоставить другим слоям.

Я собираюсь реализовать Данные в виде Списка <>, но я помню, что читал кое-что о том, как не предоставлять тип Списка потребителям, если в этом нет необходимости.

public List<User> GetAllUsers() // non C# users: that means List of User :)

Знаете ли вы, почему (Google не помог)? Что вы обычно выставляете для такого рода вещей? IList? IEnumerable?

Ответы [ 3 ]

6 голосов
/ 14 октября 2008

Обычно лучше всего использовать наименее мощный интерфейс, с которым пользователь все еще может работать. Если пользователю просто нужны перечисляемые данные, верните IEnumerable<User>. Если этого недостаточно, потому что пользователь должен иметь возможность изменять список (внимание! Это не всегда так), вернуть IList<User>.

/ EDIT:

Джоэл задает действительный вопрос в своем комментарии: почему действительно предоставляется наименее мощный интерфейс вместо предоставления пользователю максимальной мощности? (Перефразировал)

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

Что еще более важно, это раскрывает части внутренней реализации через тип возвращаемого значения. Если мне нужно изменить реализацию в будущем, чтобы она больше не использовала контейнер IList, у меня возникает проблема: мне нужно либо изменить контракт метода, введя изменение, нарушающее сборку. Или мне нужно скопировать данные в контейнер списка.

В качестве примера представьте, что эффективная реализация использует словарь и просто возвращает коллекцию Values, которая не реализует IList.

3 голосов
/ 14 октября 2008

Определенно что-то есть. Использование интерфейса уменьшит связь и облегчит изменение деталей реализации уровня данных в будущем. Какой интерфейс зависит от обстоятельств. IList хорош, но иногда вам может понадобиться функциональность ICollection или вы хотите указать значения, доступные только для чтения.

2 голосов
/ 14 октября 2008

Вы должны тщательно подумать, прежде чем возвращать IEnumerable. Если базовый код использует «yield» для генерации IEnumerable или использует LINQ, вы в конечном итоге будете держать открытыми любые используемые ресурсы.

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

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

...