2010-11-08 3 views
2

Нужно ли инкапсулировать коллекции?Нужно ли инкапсулировать коллекции?

говорят

private List<Item> items; 

public Items Items 
{ 
    get { return this.items; } 
    set { this.items= value; } 
} 

или просто

public List<Item> Items; 

EDIT:

  • Есть ли способ, чтобы привязать к коллекции, не подвергая общественности добытчика?
+3

Не так много инкапсуляции ... – CesarGon

ответ

4

Я обычно выставляю коллекции только для чтения. Обычно нет необходимости назначать новую коллекцию. Я создам экземпляр коллекции один раз в конструкторе или получателе свойств. Это уменьшает вероятность нулевых опорных ошибок.

+0

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

+0

«Это уменьшает вероятность ошибок нулевой ссылки». Я думаю, что подход является общим для всех членов класса, а не специально для коллекций. – serhio

+0

IMO, есть не только «нет причин назначать новую коллекцию», она может иметь побочные эффекты. См. Мой ответ. –

3

Публикация коллекций - неплохая идея. Хотя инкапсулирующие поля важны в любом случае, коллекции еще важнее.

Сама коллекция, как правило, не является объектом, о котором вы действительно заботитесь. Таким образом, вызывающий абонент вашего класса не сможет его установить, заменить или удалить (скажем: установить на null). Он должен заботиться только об элементах. Если вы позволите установить экземпляр списка извне, вы рискуете, что несколько экземпляров вашего класса имеют один и тот же экземпляр списка. Это будет иметь некоторые неприятные побочные эффекты.

Ваш класс несет ответственность (как минимум), чтобы создать экземпляр списка, чтобы убедиться, что он является выделенным списком и никогда не является нулевой ссылкой.

Публикация списка публичным геттером на самом деле напоминает его полную демонстрацию. Это минимальная инкапсуляция, которую вы должны делать, это фактически не инкапсуляция вообще.

Полная инкапсуляция выполняется только путем выставления элементов как IEnumerable и предоставления операций добавления, удаления, подсчета и аналогичных операций в отдельных методах или свойствах. Чем больше вам нужно, тем больше становится сложнее. Это полезно, если вам действительно не нужно много основных операций извне и управлять как можно больше в классе.

+0

sometiles Мне нужно привязать к 'myObject.Items', поэтому мне нужно экрнализировать коллекцию. – serhio

+0

, в этом случае вы все равно можете манипулировать коллекцией. Items.Clear(), Items.Clear(), Items.Add, Items.Remove и т. Д. – hunter

+0

«разоблачение элементов как IEnumerable» - вы всегда можете отнести его к исходному «списку» ' – serhio

1

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

public class PotOfUnicorns 
{ 

    private List<Item> items = new List<Item>(); 

    public Items Items 
    { 
     get { return this.items; } 
     private set { this.items= value; } 
    } 

} 
1

Несколько раз я подключить его как так ....

List<Item> _items; 
public Items Items 
{ 
    get 
    { 
     if (_items == null) _items = new List<Items>(); 
     return _items; 
    } 
    private set { _items = value; } 
} 
2

Общественные поля, вообще говоря, с неодобрением в мире .NET. Кроме того, также недооценивается returning null collections от методов или свойств. Поэтому я определенно «инкапсулирую» коллекцию.

1

Вам не советуют публиковать коллекционеры решений по сбору информации; см. this rule на MSDN. Еще лучше использовать только интерфейс, а не конкретный тип.

class Example 
{ 
    public Example() 
    { 
     this.MyList = new List<string>(); 
    } 

    public IList<string> MyList { get; private set; } 
} 
1

Создание пользовательской коллекции, чтобы обернуть стандартный набор, так что вы можете контролировать то, что ваши абоненты сделать это лучший вариант, однако имеет затраты.

Я думаю, что это сводится к тому, сколько различным людям будут писать код против объектной модели и погоды этих людей являются частью одной команды как вы.

Вы останавливаете вызывающих, делающих «плохие вещи», путем инкапсуляции вашей коллекции; это, скорее всего, сохранит время отладки вызывающих абонентов, а также упростит работу ваших абонентов, как использовать ваш API.

Так что это торговля между вашим временем и временем программистов, которые будут использовать вашу объектную модель.

Смежные вопросы