Инкапсулировать коллекцию в C #

Начиная с версии 3.0 C # имеет отличный синтаксический сахар, такой как авто-свойства, которые значительно упрощают реализацию принципа инкапсуляции. Это хорошо, если вы используете его с атомарными значениями, поэтому вы можете заменить шаблон инкапсуляции следующим образом:

private string _name;

public string Name 
{
  get { return _name; }
  set { _name = value; }
}

всего одной строкой:

public string FirstName  { get; set; }

Мне очень нравится эта замечательная функция, поскольку она экономит много времени разработчиков.


Но все не так хорошо, когда вы создаете свойство, указывающее на коллекцию. Обычно я вижу, что свойства коллекции реализованы одним из двух способов.

1) Без автоматических свойств, чтобы можно было использовать инициализатор поля:

private List<string> _names = new List<string>();

public List<string> Names
{
    get { return _names; }
}

2) Использование автоматических свойств.Этот подход приемлем, если у класса только один конструктор:

public List<string> Names { get; private set; }

public .ctor()
{
    Names = new List<string>();
}

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

Что касается меня, то в отношении шаблона Encapsulate Collection правильная реализация инкапсуляции коллекции должна выглядеть так:

private readonly List<string> _names = new List<string>();

public ICollection<string> Names
{
    get { return new ReadOnlyCollection<string>(_names); }
}

public void Add_Name(string name)
{
    _names.Add(name);
}

public void Remove_Names(string name)
{
    _names.Remove(name);
}

public void Clear_Names()
{
    _names.Clear();
}

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

Интересно, почему команда C # не предоставляет какой-то ясный и простой способ определения автоматических свойств коллекции, чтобы разработчики могли удовлетворить свою лень, создав надежный код?

22
задан Vitaliy Ulantikov 16 September 2011 в 14:22
поделиться