Неизменные коллекции? - PullRequest
19 голосов
/ 29 мая 2009

Я делаю большинство моих основных типов в своем приложении неизменяемыми. Но должны ли коллекции быть неизменными? Мне кажется, что это огромные накладные расходы, если я что-то упустил.

Я говорю о коллекциях для хранения значений Point3 и т. Д., Которые можно добавлять по мере необходимости. Поэтому, если в коллекции есть 1M значений, и вам нужно удалить 1 из них, вам придется заново создавать одну и ту же коллекцию, верно?

Ответы [ 10 ]

26 голосов
/ 29 мая 2009

У Эрика Липперта есть серия об неизменности в C #, и если вы прочитаете его полностью, он реализует несколько разных неизменных коллекций:

  1. Неизменяемость в C # Часть первая: Виды неизменности
  2. Неизменяемость в C # Часть вторая: Простой неизменяемый стек
  3. Неизменяемость в C # Часть третья: ковариантный неизменяемый стек
  4. Неизменяемость в C # Часть четвертая: неизменяемая очередь
  5. Неизменяемость в C # Часть пятая: LOLZ!
  6. Неизменяемость в C # Часть шестая: простое двоичное дерево
  7. Неизменяемость в C # Часть седьмая: подробнее о двоичных деревьях
  8. Неизменяемость в C # Часть восьмая: еще больше о двоичных деревьях
  9. Неизменяемость в C # Часть девятая: Академическая? Плюс моя реализация дерева AVL
  10. Неизменяемость в C # Часть десятая: двусторонняя очередь
  11. Неизменяемость в C #, часть одиннадцатая: рабочая двусторонняя очередь
15 голосов
/ 24 декабря 2012

Неизменяемые коллекции великолепны, особенно если ваше приложение уже использует неизменяемые типы или семантику.

.NET только что отправил свои первые неизменные коллекции , которые я предлагаю вам попробовать.

8 голосов
/ 29 мая 2009

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

Обычно ваша коллекция представляет что-то, верно? Это коллекция собак или коллекция счетов ...

Обычно есть что-то, что вы можете сделать с коллекцией собак (Herd? Neuter?) Или коллекцией счетов (платно?). Практически всегда есть операции, которые применяются ко всему списку объектов - операции, которые имеют функциональность за исключением единственного invoice.pay () (например, гарантируя, что самые важные счета оплачиваются первыми), без класса вокруг вашей коллекции, на самом деле нет места для размещения этих операций.

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

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

2 голосов
/ 29 мая 2009

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

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

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

2 голосов
/ 29 мая 2009

Если вы только когда-либо добавите / удалите начало или конец, вы можете обмануть - но в целом; да: вы должны создавать новую коллекцию для каждого изменения.

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

0 голосов
/ 11 апреля 2012

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

0 голосов
/ 29 мая 2009

Это зависит от стиля, в котором написана / разработана ваша программа.

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

И, как и в функциональных языках, вам следует использовать связанные списки, которые можно построить в O (1) для каждого элемента (cons) и обрабатывать их функционально (рекурсии, создание новых списков из списков).

Когда вашей программе требуются императивные коллекции (массивы, векторы / списки), сохраняйте их изменяемыми.

0 голосов
/ 29 мая 2009

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

0 голосов
/ 29 мая 2009

Если у вас есть коллекция, в которую вы можете добавлять элементы после ее создания, она не является неизменной

0 голосов
/ 29 мая 2009

Все зависит от того, кто использует коллекции одновременно. Строки неизменяемы, чтобы бу-бу, как два потока, пытались удалить первый символ одновременно.

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