32

I have the following code in a public static class:

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

.. but even using readonly I can still add items to the list from another class:

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

or

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

Is there a way to make the thing read only without changing the implementation of CharList (it'll break some stuff)? If I do have to change the implementation (to make it non-changeable), what would be the best way? I need it to be List<T, T>, so ReadOnlyCollection won't do

ForceMagic
  • 6,230
  • 12
  • 66
  • 88
Richard
  • 439
  • 1
  • 4
  • 6

3 Answers3

61

The modifier readonly means that the value cannot be assigned except in the declaration or constructor. It does not mean that the assigned object becomes immutable.

If you want your object to be immutable, you must use a type that is immutable. The type ReadOnlyCollection<T> that you mentioned is an example of a immutable collection. See this related question for how to achieve the same for dictionaries:

Community
  • 1
  • 1
Mark Byers
  • 811,555
  • 193
  • 1,581
  • 1,452
  • The question mentions "I need it to be List, so ReadOnlyCollection won't do", and there is no `ReadOnlyDictionary` that I am aware of. –  Apr 08 '12 at 21:38
  • See the link I added "Is there a read-only generic dictionary available in .NET?" – Mark Byers Apr 08 '12 at 21:39
  • 3
    Huh. As hinted in an answer in that question, as it turns out, .NET 4.5 does have a `ReadOnlyDictionary` already. Cool. –  Apr 08 '12 at 21:41
  • @hvd: Nice find, I missed that. Did you vote it up? The more votes it has, the more likely people will see it. – Mark Byers Apr 08 '12 at 21:44
3

The readonly modifier just gaurantees that the variable 'CharList' cannot be re-assigned to something else from outside of the class constructor. You need to create your own dictionary structure that doesn't have a public Add() method.

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); 
    }
}

Or, if you truly can't change the implementation, make the SortedList private and add your own methods that control access to it:

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

    // public indexer
    public List<myObj> this[int index]
    {
        get { return this.CharList[index]; }
    }
}
Sean Thoman
  • 7,429
  • 6
  • 56
  • 103
1

The List have the AsReadOnly method that return a read only list should be what you want.

aleroot
  • 71,077
  • 30
  • 176
  • 213