ReadOnlyDictionary之应用场景
ReadOnlyDictionary之应用场景
本文地址:http://www.cnblogs.com/AndersLiu/archive/2009/04/17/usage-of-readonly-dictionary.html
作者:Anders Liu
前两天发布了《隐藏接口实现 及 ReadOnlyDictionary》一文,有不少朋友提出疑问。其中一个主要问题就是,这样做真的可以实现“只读”吗?如果还有其他变量引用了ReadOnlyDictionary所包装的普通字典,依然可以通过另外这个变量来修改字典中的内容。有朋友甚至提到了,可以在创建ReadOnlyDictionary时,将原有字典中的内容复制出一份,来做到真正的“只读”。
其实,这些主要是因为我对这个类的应用场景没有介绍清楚的缘故。其实我这里提到的ReadOnlyDictionary也好,.NET提供的ReadOnlyCollection也罢,其目的并不是让整个字典(或集合)真的“只读”,而是希望某些具有字典(或集合)性质类成员,能够做到“在当前类中可读写,在类的外部只读”。
考虑这样一个场景,我要实现一个FileStructure类,表示文件结构,其中包含了多个Field。每个FileStructure里的每个Field都具有不同的名字,我希望用户能够用名字检索到对应的字段,所以最好的方式是将字段保存在一个字典中。
public class FileStructure { public Dictionary<string, Field> Fields { get { return _fields; } } public FileStructure() { _fields = new Dictionary<string, Field>(); _fields.Add("DosHeader", new Field(...)); _fields.Add("PEHeader", new Field(...)); _fields.Add("OptionalHeader", new Field(...)); } private Dictionary<string, Field> _fields; }
上面的代码虽然保证了Fields属性是只读的——可以确保用户无法用自己的字典实例来替换FileStructure所有的——但却不能防止用户自己向Fields属性中添加其他字段。
如果使用ReadOnlyDictionary,就能很好地避免这一问题。
public class FileStructure { public ReadOnlyDictionary<string, Field> Fields // Change ‘Dictionary’ to ‘ReadOnlyDictionary’ { get { return _roFields; } // Change '_fields' to '_roFields' } public FileStructure() { _fields = new Dictionary<string, Field>(); _roFields = new ReadOnlyDictionary<string, Field>(_fields); // Added _fields.Add("DosHeader", new Field(...)); _fields.Add("PEHeader", new Field(...)); _fields.Add("OptionalHeader", new Field(...)); } private Dictionary<string, Field> _fields; private ReadOnlyDictionary<string, Field> _roFields; // Added }
现在,就不怕用户“擅自”修改字典中的内容了。
在ReadOnlyDictionary的实现中,并没有复制所包装的字典中的内容。这样做的好处是显而易见的——其一,节省空间。其二,ReadOnlyDictionary能够及时反映内部普通字典上发生的变化;也就是说,如果在类的“内部”向字典中添加了新值,或修改了某些条目,则在类的“外部”可以从之前拿到的只读字典中,访问到这些变化过的条目。
链接:
- 访问《隐藏接口实现 及 ReadOnlyDictionary》——http://www.cnblogs.com/AndersLiu/archive/2009/04/16/hide-interface-member-and-readonly-dictionary.html
- 下载ReadOnlyDictionary——https://files.cnblogs.com/AndersLiu/ReadOnlyDirectionary.zip
(完)