Возвратите набор как только для чтения

Существует также менее «хакерский» метод, который работает для всех популярных браузеров. Google включил проверку браузера в Closure Library . В частности, посмотрите на goog.userAgent и goog.userAgent.product . Таким образом, вы также обновляетесь, если что-то изменится в том, как отображаются браузеры (учитывая, что вы всегда используете последнюю версию компилятора закрытия.)

20
задан alastairs 23 July 2012 в 21:50
поделиться

7 ответов

Если Ваши базовые данные хранятся как список, можно использовать Список (T) метод.AsReadOnly .
, Если Ваши данные могут быть перечислены, можно использовать Счетный. Метод ToList для кастинга набора, чтобы Перечислить и назвать AsReadOnly на нем.

31
ответ дан 29 November 2019 в 22:29
поделиться

Если Ваше единственное намерение состоит в том, чтобы заставить код вызова не делать ошибку и изменять набор, когда это должно только читать все, что необходимо, должен возвратить интерфейс, который не поддерживает, Добавляют, Удаляют, и т.д. Почему бы не возвратиться IEnumerable<string>? Код вызова должен был бы бросить, который они вряд ли обойдутся без знания внутренностей свойства, к которому они получают доступ.

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

19
ответ дан 29 November 2019 в 22:29
поделиться

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

3
ответ дан 29 November 2019 в 22:29
поделиться

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

Это выглядело бы примерно так:

List<string> _Data;
public IEnumerable<string> Data
{
  get
  {
    foreach(string item in _Data)
    {
      return yield item;
    }
  }
}
3
ответ дан 29 November 2019 в 22:29
поделиться

Я думаю, что Вы путаете понятия здесь.

Эти ReadOnlyCollection обеспечивает обертку только для чтения для существующего набора, позволяя Вам (Класс A) раздавать ссылку на набор, безопасный в знании, что вызывающая сторона (Класс B) не может изменить набор (т.е. не может добавлять , или удаляют любые элементы из набора.)

нет абсолютно никаких гарантий потокобезопасности.

  • , Если Вы (Класс A) продолжаете изменять базовый набор после раздачи его как ReadOnlyCollection затем, класс B будет видеть эти изменения, иметь любые делаемые недействительным итераторы, и т.д. и обычно будет открыт для любой из обычных проблем параллелизма с наборами.
  • Кроме того, если элементы в наборе изменяемы, и Вы (Класс A) и , вызывающая сторона (Класс B) сможет изменить любое изменяемое состояние объектов в наборе.

Ваша реализация зависит от Ваших потребностей: - если Вы не заботитесь о вызывающей стороне (Класс B) от наблюдения дальнейших изменений в наборе затем, можно просто клонировать набор, раздать его и прекратить заботиться. - При определенной необходимости в вызывающей стороне (Класс B) для наблюдения изменений, которые внесены в набор, и Вы хотите, чтобы это было ориентировано на многопотоковое исполнение, затем у Вас есть больше проблемы на Ваших руках. Одна возможность состоит в том, чтобы реализовать Ваш собственный ориентированный на многопотоковое исполнение вариант ReadOnlyCollection для предоставления заблокированного доступа, хотя это будет нетривиально и непроизводительно, если Вы захотите поддерживать IEnumerable, и это все еще не защитит Вас от изменяемых элементов в наборе.

11
ответ дан 29 November 2019 в 22:29
поделиться

Можно использовать копию набора вместо этого.

public IList<string> Data {
get {
    return new List<T>(data);
}}

Тот способ, которым не имеет значения, если это обновляется.

2
ответ дан 29 November 2019 в 22:29
поделиться

Я проголосовал за ваш принятый ответ и согласен с ним, но могу ли я предложить вам кое-что для рассмотрения?

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

Основное преимущество этого состоит в том, что вы не можете добавлять код в коллекции, поэтому всякий раз, когда у вас есть собственная «коллекция» в вашей объектной модели, у вас ВСЕГДА есть не-объектно-ориентированный код поддержки, распространенный по всему проекту для доступа к нему.

Например, если ваша коллекция представляет собой счета-фактуры, у вас, вероятно, будет 3 или 4 места в вашем коде, где вы перебираете неоплаченные счета. У вас может быть метод getUnpaidInvoices. Однако настоящая сила проявляется, когда вы начинаете думать о таких методах, как «payUnpaidInvoices (плательщик, счет);».

Когда вы передаете коллекции вместо написания объектной модели, вам никогда не придут в голову целые классы рефакторинга.

Обратите внимание, что это делает вашу проблему особенно приятной. Если вы не хотите, чтобы люди меняли коллекции, ваш контейнер не должен содержать мутаторов. Если позже вы решите, что только в одном случае вы действительно ДОЛЖНЫ его изменить, вы можете создать безопасный механизм для этого.

Как вы решите эту проблему, когда вы передаете собственную коллекцию?

Кроме того, native коллекции не могут быть дополнены дополнительными данными. Вы узнаете это в следующий раз, когда обнаружите, что передаете (Collection, Extra) более чем одному или двум методам. Он указывает, что «Extra» принадлежит объекту, содержащему вашу коллекцию.

Вам никогда не придут в голову целые классы рефакторинга.

Отметьте также, что это делает вашу проблему особенно приятной. Если вы не хотите, чтобы люди меняли коллекции, ваш контейнер не должен содержать мутаторов. Если позже вы решите, что только в одном случае вы действительно ДОЛЖНЫ его изменить, вы можете создать безопасный механизм для этого.

Как вы решите эту проблему, когда вы передаете собственную коллекцию?

Кроме того, native коллекции не могут быть дополнены дополнительными данными. Вы узнаете это в следующий раз, когда обнаружите, что передаете (Collection, Extra) более чем одному или двум методам. Он указывает, что «Extra» принадлежит объекту, содержащему вашу коллекцию.

вам никогда не придет в голову целый класс рефакторинга.

Обратите внимание, что это делает вашу проблему особенно приятной. Если вы не хотите, чтобы люди меняли коллекции, ваш контейнер не должен содержать мутаторов. Если позже вы решите, что только в одном случае вы действительно ДОЛЖНЫ его изменить, вы можете создать безопасный механизм для этого.

Как вы решите эту проблему, когда вы передаете собственную коллекцию?

Кроме того, native коллекции не могут быть дополнены дополнительными данными. Вы узнаете это в следующий раз, когда обнаружите, что передаете (Collection, Extra) более чем одному или двум методам. Он указывает, что «Extra» принадлежит объекту, содержащему вашу коллекцию.

ваш контейнер не должен содержать мутаторов. Если позже вы решите, что только в одном случае вы действительно ДОЛЖНЫ его изменить, вы можете создать безопасный механизм для этого.

Как вы решаете эту проблему, когда передаете собственную коллекцию?

Кроме того, native коллекции не могут быть дополнены дополнительными данными. Вы узнаете это в следующий раз, когда обнаружите, что передаете (Collection, Extra) более чем одному или двум методам. Он указывает, что «Extra» принадлежит объекту, содержащему вашу коллекцию.

ваш контейнер не должен содержать мутаторов. Если позже вы решите, что только в одном случае вы действительно ДОЛЖНЫ его изменить, вы можете создать безопасный механизм для этого.

Как вы решаете эту проблему, когда передаете собственную коллекцию?

Кроме того, native коллекции не могут быть дополнены дополнительными данными. Вы узнаете это в следующий раз, когда обнаружите, что передаете (Collection, Extra) более чем одному или двум методам. Он указывает, что «Extra» принадлежит объекту, содержащему вашу коллекцию.

Вы узнаете это в следующий раз, когда обнаружите, что передаете (Collection, Extra) более чем одному или двум методам. Он указывает, что «Extra» принадлежит объекту, содержащему вашу коллекцию.

Вы узнаете это в следующий раз, когда обнаружите, что передаете (Collection, Extra) более чем одному или двум методам. Он указывает, что «Extra» принадлежит объекту, содержащему вашу коллекцию.

19
ответ дан 29 November 2019 в 22:29
поделиться
Другие вопросы по тегам:

Похожие вопросы: