Что такое коллекция только для чтения?

Я запустил аналитик кода безопасности и обнаружил, что у меня появилось предупреждение CA2105. Я посмотрел на пример фальсификации оценок. Я не знал, что вы можете назначить int[] int только для чтения. Я думал, что readonly похож на const С++ и делает его незаконным.

В разделе «Как исправить нарушения» предлагается клонировать объект (чего я не хочу делать) или «Заменить массив строго типизированной коллекцией, которую нельзя изменить». Я щелкнул ссылку и увидел «ArrayList» и добавил каждый элемент один за другим, и не похоже, что вы можете предотвратить добавление чего-либо еще.

Итак, когда у меня есть этот фрагмент кода, какой самый простой или лучший способ сделать его коллекцией только для чтения?

public static readonly string[] example = { "a", "b", "sfsdg", "sdgfhf", "erfdgf", "last one"};

person Community    schedule 21.04.2010    source источник
comment
возможный дубликат Вернуть коллекцию только для чтения   -  person nawfal    schedule 11.11.2013
comment
A readOnlyCollection = Обычная коллекция — Добавить/удалить API — Установить индексатор   -  person RBT    schedule 20.02.2017


Ответы (4)


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

ReadOnlyCollection

Пример из MSDN:

List<string> dinosaurs = new List<string>();
dinosaurs.Add("Tyrannosaurus");
dinosaurs.Add("Amargasaurus");
dinosaurs.Add("Deinonychus");
dinosaurs.Add("Compsognathus");

ReadOnlyCollection<string> readOnlyDinosaurs = new ReadOnlyCollection<string>(dinosaurs);
person Mikael Svenson    schedule 21.04.2010

public static readonly ReadOnlyCollection<string> example
    = new ReadOnlyCollection<string>(new string[] { "your", "options", "here" });

(хотя, вероятно, его следует отображать как свойство get, а не как общедоступное поле)

person Marc Gravell    schedule 21.04.2010
comment
Я бы также хотел использовать ключевое слово readonly для переменной. Без этого у кого-то может сложиться впечатление, что, поскольку коллекция имеет тип ReadOnlyCollection, я полностью защищен от любой возможности внесения изменений в мою коллекцию, когда это не так. Можно не осознавать, что коллекция доступна только для чтения, но переменная, указывающая на нее, — нет. Что будет означать ReadOnlyCollection, если я могу полностью переназначить саму переменную новой коллекции. +1. - person RBT; 17.02.2017
comment
@RBT обратите внимание, что readonly - это ложь; поля только для чтения могут быть абсолютно изменены. Придется, конечно, немного схитрить... - person Marc Gravell; 17.02.2017
comment
Мне потребовалось некоторое время, чтобы переварить это. Спасибо, что показали мне свет. - person RBT; 23.02.2017

Если вы работаете с массивами, вы можете использовать

return Array.AsReadOnly(example);

чтобы обернуть ваш массив в коллекцию только для чтения.

person Steve Dennis    schedule 21.04.2010

Я искал похожее решение, но хотел по-прежнему иметь возможность изменять коллекцию внутри класса, поэтому выбрал описанный здесь вариант: http://www.csharp-examples.net/readonly-коллекция/

Короче говоря, его пример:

public class MyClass
{
    private List<int> _items = new List<int>();

    public IList<int> Items
    {
        get { return _items.AsReadOnly(); }
    }
}
person nelsonmichael    schedule 21.02.2013