9

I have a class in C# that contains a Dictionary, which I want to create and ensure nothing as added, edited or removed from this dictionary as long as the class which contains it exists.

readonly doesn't really help, once I tested and saw that I can add items after. Just for instance, I created an example:

public class DictContainer
{
    private readonly Dictionary<int, int> myDictionary;

    public DictContainer()
    {
        myDictionary = GetDictionary();
    }

    private Dictionary<int, int> GetDictionary()
    {
        Dictionary<int, int> myDictionary = new Dictionary<int, int>();

        myDictionary.Add(1, 2);
        myDictionary.Add(2, 4);
        myDictionary.Add(3, 6);

        return myDictionary;
    }

    public void Add(int key, int value)
    {
        myDictionary.Add(key, value);
    }

}

I want the Add method not to work. If possible, I want it not to even compile. Any suggestions?

Actually, I'm worried for it is code that will be open for a lot of people to change. So, even if I hide the Add method, it will be possible for someone to "innocently" create a method which add a key, or remove another. I want people to look and know they shouldn't change the dictionary in any ways. Just like I have with a const variable.

Samuel Carrijo
  • 17,449
  • 12
  • 49
  • 59
  • 2
    Strange requirements suggest your design has issues. You might want to rethink what you're attempting here. Otherwise, you can easily create your own implementation that does this. –  May 12 '09 at 16:57
  • 3
    You can implement your own Dictionary. Similar question: http://stackoverflow.com/questions/35002/does-c-have-a-way-of-giving-me-an-immutable-dictionary – bruno conde May 12 '09 at 16:57

7 Answers7

8

Hide the Dictionary totally. Just provide a get method on the DictContainer class that retrieves items from the dictionary.

public class DictContainer
{
    private readonly Dictionary<int, int> myDictionary;

    public DictContainer()
    {
        myDictionary = GetDictionary();
    }

    private Dictionary<int, int> GetDictionary()
    {
        Dictionary<int, int> myDictionary = new Dictionary<int, int>();

        myDictionary.Add(1, 2);
        myDictionary.Add(2, 4);
        myDictionary.Add(3, 6);

        return myDictionary;
    }

    public this[int key]
    {
        return myDictionary[key];
    }
}
Neil Barnwell
  • 41,080
  • 29
  • 148
  • 220
2

Don't define the Add Method.

Keep the myDictionary variable private and expose a Getter/Indexer so that it can only be read from outside that class..

cigien
  • 57,834
  • 11
  • 73
  • 112
Eoin Campbell
  • 43,500
  • 17
  • 101
  • 157
1

There's no built-in way to do that, consider using a wrapper class.

Steven
  • 166,672
  • 24
  • 332
  • 435
arul
  • 13,998
  • 1
  • 57
  • 77
0

FYI, now it is built-in to .net 4.5.

http://msdn.microsoft.com/en-us/library/gg712875(v=vs.110).aspx

batbaatar
  • 5,448
  • 2
  • 20
  • 26
0

Similar to Neil's answer:

Hide the Dictionary totally. Just provide a get method on the DictContainer class that retrieves items from the dictionary. If you want to use [] override you need getter settter method (atleast any one get/set)

public class DictContainer
{
    private readonly Dictionary<int, int> myDictionary;

    public DictContainer()
    {
        myDictionary = GetDictionary();
    }

    private Dictionary<int, int> GetDictionary()
    {
        Dictionary<int, int> myDictionary = new Dictionary<int, int>();

        myDictionary.Add(1, 2);
        myDictionary.Add(2, 4);
        myDictionary.Add(3, 6);

        return myDictionary;
    }

    public this[int key]
    {
        get => myDictionary[key];
    }
}
cigien
  • 57,834
  • 11
  • 73
  • 112
GVyas
  • 27
  • 6
  • @cigien I have changed the function to make it work => public this[int key] { get => myDictionary[key]; } – GVyas Dec 30 '21 at 07:01
  • I'm not sure what you mean. If you want to make edits to your answer to clarify something, please go ahead. – cigien Dec 30 '21 at 13:37
0
interface IReadOnlyDic<Key, Value>
{
    void Add(Key key, Value value);
}
class ReadOnlyDic<Key, Value> : Dictionary<Key, Value>, IReadOnlyDic<Key, Value>
{
    public new void Add(Key key, Value value)
    {
        //throw an exception or do nothing
    }
    #region IReadOnlyDic<Key,Value> Members

    void IReadOnlyDic<Key, Value>.Add(Key key, Value value)
    {
        base.Add(key, value);
    }

    #endregion
}

to add custom items;

    IReadOnlyDic<int, int> dict = myDictInstance as IReadOnlyDic<int, int>;
    if (dict != null)
        dict.Add(1, 155);
Tolgahan Albayrak
  • 3,118
  • 1
  • 25
  • 28
0

and this is another way

class ReadOnlyDic<Key, Value> : Dictionary<Key, Value>
{
    private bool _locked = false;

    public new void Add(Key key, Value value)
    {
        if (!_locked)
        {
            base.Add(key, value);
        }
        else
        {
            throw new ReadOnlyException();
        }
    }
    public void Lock()
    {
        _locked = true;
    }
}
Tolgahan Albayrak
  • 3,118
  • 1
  • 25
  • 28
  • +1 for the simplicity of the solution, and for compatibility with the Dictionary's interfaces. However: Why using "new" instead of "override"? Further, besides the Add, the Remove method should be overridden, too. – chiccodoro May 06 '10 at 08:33
  • @chiccodoro: `Dictionary` does not have `virtual` methods. – SLaks May 10 '10 at 17:27