Должен ли список <T>быть закрытым? - PullRequest
11 голосов
/ 05 октября 2010

Мне нужно ваше мнение по этому поводу, потому что я прочитал много разных вещей на эту тему. Если у вас есть List<T> или любой другой список в объявлении класса, вы делаете его закрытым, а затем добавляете или удаляете элементы, используя определенные методы, или вы делаете его общедоступным?

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

В качестве примера, скажем, у нас есть class Employer с закрытыми полями name и List<Employees>. Мой вопрос заключается в том, должны ли мы сделать список сотрудников частным или общедоступным, и каковы будут преимущества / недостатки в любом случае.

Ответы [ 5 ]

6 голосов
/ 05 октября 2010

для List явно да, он должен быть закрытым, в зависимости от того, какие функциональные возможности должны быть доступны для вас, лучше выбрать такие интерфейсы, как IEnuemerable, ICollection или IList или если вы выставляете коллекцию. См. Ответ SLaks.

В целом, разоблачение внутренней структуры и состояния является плохой идеей, и, поскольку ваш объект типа List является и тем и другим, вы хотели бы сохранить его внутренним. Возможно, имеет смысл дать пользователю возможность перебирать его, добавлять или удалять элементы, но вы все равно должны сохранять внутренний список и либо предоставлять методы Add / Remove, либо, как минимум, предоставлять интерфейс, позволяющий изменять тип внутреннего представления без влияния на открытый интерфейс.

Более того, если вы используете интерфейс, вам следует выбрать самый узкий интерфейс.

Так что, если клиентскому коду нужно только перечислить его. используйте IEnumerable, если клиентскому коду необходимо индексировать, используйте ICollection и т. д.

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

РЕДАКТИРОВАТЬ после обновления Что касается вашего примера. Спросите себя, имеет ли смысл, что кто-либо, кроме Работодателя, может изменить, кто его сотрудники? для меня это в словах, которые вы уже выбрали. Работодатель нанимает Работника и должен полностью контролировать, кем являются его / ее сотрудники. Так что в этом конкретном случае я бы оставил это в тайне и раскрыл Hire (сотрудник IEmployee) и Fire (сотрудник IEmployee) таким образом, чтобы код явно указывал намерение

4 голосов
/ 05 октября 2010

Если вам нужно предоставить коллекцию пользователям вашего класса, вы должны создать свойство только для чтения с System.Collections.ObjectModel.Collection<T>.

Затем вы можете наследовать этот класс и переопределить InsertItem, RemoveItem и SetItem для запуска пользовательской логики, когда пользователь манипулирует коллекцией.

Если вы не хотите, чтобы пользователь мог изменять коллекцию, вы должны предоставить ReadOnlyCollection<T>.

В вашем конкретном примере вам, вероятно, следует предоставить ReadOnlyCollection<Employee> с отдельными методами мутатора в Employer.

3 голосов
/ 05 октября 2010

И если вам нужно, чтобы кто-то мог перечислить список, вы можете предоставить iEnumerable, функция GetEnumerator которого просто вызовет функцию GetEnumerator списка.

1 голос
/ 05 октября 2010

В соответствии с каталогом рефакторинга всегда лучше инкапсулировать коллекции.Это предотвращает случайное прерывание данных кем-либо путем добавления или удаления элементов из списка.Если вам не нужна функциональность защиты ваших данных от случайных изменений, вы можете вернуть обычный список.

Предоставляя методы Add и Remove, вы получаете преимущество в том, что любые изменения происходят только через эти методы.

0 голосов
/ 05 октября 2010

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

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