Ключевое слово readonly не делает список <> ReadOnly?

У меня есть следующий код в общедоступном статическом классе:

public static class MyList
{
    public static readonly SortedList<int, List<myObj>> CharList;
    // ...etc.
}

.. но даже используя readonly, я все же могу добавить элементы в список из другого класса:

MyList.CharList[100] = new List<myObj>() { new myObj(30, 30) };

или

MyList.CharList.Add(new List<myObj>() { new myObj(30, 30) });

Есть ли способ сделать чтение только без изменения реализации CharList (это сломает некоторые вещи)? Если мне нужно изменить реализацию (чтобы сделать ее непеременной), что было бы лучше всего? Мне нужно, чтобы он был List < T, T > , поэтому ReadOnlyCollection не будет выполнять

Ответ 1

Модификатор readonly означает, что значение не может быть назначено, кроме как в объявлении или конструкторе. Это не означает, что назначенный объект становится неизменным.

Если вы хотите, чтобы ваш объект был неизменным, вы должны использовать неизменяемый тип. Тип ReadOnlyCollection<T>, который вы упомянули, является примером неизменяемой коллекции. См. Этот связанный вопрос о том, как добиться того же для словарей:

Ответ 2

Модификатор только для чтения просто гарантирует, что переменная "CharList" не может быть повторно назначена на что-то другое из-за пределов конструктора класса. Вам нужно создать собственную структуру словаря, которая не имеет общедоступного метода Add().

class ImmutableSortedList<T, T1> 
{
    SortedList<T, T1> mSortedList;

    public ImmutableSortedList(SortedList<T, T1> sortedList) // can only add here (immutable)
    {
        this.mSortedList = sortedList; 
    }

    public implicit operator ImmutableSortedList<T, T1>(SortedList<T, T1> sortedList)
    {
        return new ImmutableSortedList<T, T1>(sortedList); 
    }
}

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

class MyList
{
    // private now
    readonly SortedList<int, List<myObj>> CharList;

    // public indexer
    public List<myObj> this[int index]
    {
        get { return this.CharList[index]; }
    }
}

Ответ 3

В списке есть метод AsReadOnly, который возвращает список только для чтения, который должен быть тем, что вы хотите.