const Dictionary in c#
Asked Answered
R

7

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.

Rollin answered 12/5, 2009 at 16:51 Comment(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.Bendicta
You can implement your own Dictionary. Similar question: #35502Statesmanship
K
9

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];
    }
}
Kra answered 12/5, 2009 at 16:56 Comment(0)
K
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..

Kansas answered 12/5, 2009 at 16:56 Comment(0)
S
2

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

Selfimmolating answered 12/5, 2009 at 16:56 Comment(0)
O
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);
Oberon answered 12/5, 2009 at 17:17 Comment(0)
O
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;
    }
}
Oberon answered 12/5, 2009 at 17:21 Comment(2)
+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.Khan
@chiccodoro: Dictionary does not have virtual methods.Legra
M
0

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

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

Maggee answered 11/11, 2014 at 21:52 Comment(0)
I
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];
    }
}
Insane answered 1/12, 2021 at 15:10 Comment(2)
@cigien I have changed the function to make it work => public this[int key] { get => myDictionary[key]; }Insane
I'm not sure what you mean. If you want to make edits to your answer to clarify something, please go ahead.Yarvis

© 2022 - 2024 — McMap. All rights reserved.