使字典只能在C#中读取

我有一个Dictionary<string, List>并希望将该成员公开为只读。 我看到我可以将它作为IReadOnlyDictionary<string, List> ,但我无法弄清楚如何将其作为IReadOnlyDictionary<string, IReadOnlyList>

有没有办法做到这一点? 在c ++中,我只是使用const,但C#没有。

请注意,在这种情况下,简单地使用IReadOnlyDictionary没有帮助,因为我希望只读取值。 看来唯一的方法是构建另一个IReadOnlyDictionary,并向它们添加IReadOnlyList。

另一个我不会兴奋的选择是创建实现接口IReadOnlyDictionary>的包装器,并让它保存原始实例的副本,但这似乎有点过分。

它就像将整个字典引用转换为IReadOnlyDictionary>因为Dictionary实现了IReadOnlyDictionary

顺便说一下,你不能这样做,因为你希望List值为IReadOnlyList

所以你需要这样的东西:

 var readOnlyDict = (IReadOnlyDictionary>)dict.ToDictionary(pair => pair.Key, pair => pair.Value.AsReadOnly()); 

不可改变的词典

这只是一个建议,但如果您正在寻找不可变的词典,请将System.Collections.Immutable NuGet包添加到您的解决方案中,您将能够使用它们:

 // ImmutableDictionary> var immutableDict = dict.ToImmutableDictionary(pair => pair.Key, pair => pair.Value.ToImmutableList()); 

在此处了解有关Immutable Collections的更多信息。

鉴于您专门寻找只读Dictionary>这一事实,您基本上正在寻找一个Lookup 。

Dictionary对象具有ToLookup()扩展名。

首先,您必须创建一个包含所需内容类型的新字典:

 var dicWithReadOnlyList = dic.ToDictionary( kv => kv.Key, kv => kv.Value.AsReadOnly()); 

然后你可以返回新的字典,因为IReadOnlyDictionaryDictionary的超类型。


你为什么要那样做? 因为Dictionary不是Dictionary的超类型, 即使 AB的超类型。 为什么? 请考虑以下示例:

 var dic = new Dictionary(); Dictionary dic2 = dic; // Imagine this were possible... dic2.Add(someT, someA); // ...then we'd have a type violation here, since // dic2 = dic requires some B as the value. 

换句话说, Dictionary TValue 不是协变的 。 从面向对象的角度来看,在字典的只读版本中应该可以进行协方差,但是在.NET框架中存在遗留问题会阻止这种情况(有关详细信息,请参阅此问题中以“UPDATE”开头的部分) )。

https://msdn.microsoft.com/en-us/library/acdd6hb7.aspx

您可以使用它将对象公开为只读。

你也可以使用属性get; 组; 并且只允许获得公开。

但Matias的回答似乎更合适。

如果你想返回一个只读字典,但仍然可以改变你的类中的字典和列表,你可以使用强制转换来获取列表类型。

这个例子有点人为,但展示了它是如何工作的。

 public class MyClass { Dictionary> _dictionary; public IReadOnlyDictionary> Dictionary { get { return _dictionary; } } public MyClass() { _dictionary = new Dictionary>(); } public void AddItem(string item) { IReadOnlyList readOnlyList = null; List list = null; if (!_dictionary.TryGetValue(item, out readOnlyList)) { list = new List(); _dictionary.Add(item, list); } else list = readOnlyList as List; list.Add(item); } } 

如果您的目标是使属性不可变,那么使用ReadOnlyDictionary将是最佳选择。