如何正确使用IReadOnlyDictionary?

Sin*_*atr 8 c# dictionary readonly-collection

来自msdn:

表示键/值对的通用只读集合.

但请考虑以下事项

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
    }
}
Run Code Online (Sandbox Code Playgroud)

我可以很容易地投射IReadOnlyDictionaryDictionary(任何人都可以)并改变它,同时List有很好的AsReadOnly方法.

问题:如何正确使用IReadOnlyDictionary公开的确实只读字典?

Cod*_*ter 16

.NET 4.5引入了ReadOnlyDictionary您可以使用的类型.它有一个接受现有字典的构造函数.

在针对较低版本的框架时,请使用包装器,如.NET是否有只读通用字典?C#有给予我一个不变的词典的方法吗?.

请注意,使用后一个类时,集合初始化程序语法将不起作用; 被编译为Add()调用.

  • 如果您使用的是最新版本,也可以使用[`ImmutableDictionary <>`](https://msdn.microsoft.com/en-us/library/dn467181%28v=vs.111%29.aspx).净.(这是一个铁杆不可变的类;) (2认同)
  • @Sinatr`ImputableDictionary <>`不是一个包装类,它确实是不可变的.`ReadOnlyDictionary`只是一个包装器,重要的是要注意,如果更改包装字典的内容,只读字典的内容也会改变.它是只读的,不是一成不变的! (2认同)