ReadOnlyDictionary之应用场景

ReadOnlyDictionary之应用场景

前两天发布了《隐藏接口实现 及 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能够及时反映内部普通字典上发生的变化;也就是说,如果在类的“内部”向字典中添加了新值,或修改了某些条目,则在类的“外部”可以从之前拿到的只读字典中,访问到这些变化过的条目。

链接:

(完)

posted @ 2009-04-17 17:09 Anders Liu 阅读(...) 评论(...) 编辑 收藏