How to properly use IReadOnlyDictionary?

Sinatr picture Sinatr · Sep 14, 2015 · Viewed 21.5k times · Source

From msdn:

Represents a generic read-only collection of key/value pairs.

However consider following:

class Test
{
    public IReadOnlyDictionary<string, string> Dictionary { get; } = new Dictionary<string, string>
    {
        { "1", "111" },
        { "2", "222" },
        { "3", "333" },
    };

    public IReadOnlyList<string> List { get; } =
        (new List<string> { "1", "2", "3" }).AsReadOnly();
}

class Program
{
    static void Main(string[] args)
    {
        var test = new Test();

        var dictionary = (Dictionary<string, string>)test.Dictionary; // possible
        dictionary.Add("4", "444"); // possible
        dictionary.Remove("3"); // possible

        var list = (List<string>)test.List; // impossible
        list.Add("4"); // impossible
        list.RemoveAt(0); // impossible
    }
}

I can easily cast IReadOnlyDictionary to Dictionary (anyone can) and change it, while List has nice AsReadOnly method.

Question: how to properly use IReadOnlyDictionary to make public indeed read-only dictionary ?

Answer

CodeCaster picture CodeCaster · Sep 14, 2015

.NET 4.5 introduced the ReadOnlyDictionary type that you could use. It has a constructor that accepts an existing dictionary.

When targeting lower framework versions, use the wrapper as explained in Is there a read-only generic dictionary available in .NET? and Does C# have a way of giving me an immutable Dictionary?.

Please note that when using the latter class, the collection initializer syntax won't work; that gets compiled to Add() calls.