使字典只能在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());
然后你可以返回新的字典,因为IReadOnlyDictionary
是Dictionary
的超类型。
你为什么要那样做? 因为Dictionary
不是Dictionary
的超类型, 即使 A
是B
的超类型。 为什么? 请考虑以下示例:
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将是最佳选择。