Безусловно, нет необходимости выставлять установщик для свойства Bars. Внутренне у вас есть ссылка на коллекцию, которая, как предполагает Кент, может быть помечена как Readonly. Через получатель вызывающая сторона может делать с коллекцией то, что она хочет, с помощью доступных методов (Add, Remove, Clear, AddRange и т. Д.), Но, что самое важное, они никогда не смогут изменить внутреннюю ссылку, которую вы держите на объект коллекции.
Это позволяет вам контролировать, какие методы разрешены. Как предполагает Джейми, наличие возвращаемого свойства IEnumerable
приведет к тому, что свойство Bars отобразит коллекцию только для чтения. Экспонирование IList
означает, что содержимое коллекции может быть изменено. Установщик свойства оставил бы его открытым для звонящего, чтобы он мог делать то, что он хочет, и вы больше не управляете.
Редактировать
После вопроса отредактируйте выше. Это действительно зависит от того, как будет использоваться объект Foo
.
Поскольку ваша главная задача - инициализировать Foo
из существующего списка Bar
объектов ...
IList<Bar> bars = ...some list of Bars previously constructed...
Ваш последний пример кода для Foo
заставляет вызывающую программу инициализироваться через конструктор, но затем также позволяет им изменять коллекцию через свойство
Foo foo = new Foo(bars);
...
foo.Bars.Clear();
foo.Bars.AddRange(bars);
Когда вы разрешаете инициализировать объект через конструктор, вам нужно спросить себя, почему вы это делаете. Это ...
- для удобства звонящего? Чтобы разрешить вызывающему коду указывать значения, которые впоследствии могут быть изменены через свойства.
- потому что вы хотите ограничить использование объекта? Принудительное задание значений (или определенных комбинаций значений) при построении объекта и сохранение их в течение всего срока службы объекта.
Вы должны спросить себя - хотите ли вы, чтобы вызывающая сторона могла изменять содержимое коллекции Bars после создания объекта Foo
?
Если нет - сделать свойство Bars доступным только для чтения.
Если да - добавить конструктор по умолчанию к объекту Foo
, чтобы вызывающая сторона не предоставляла список для его инициализации. Но у них будет возможность сделать это, если они захотят через перегруженный конструктор.