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 @   Anders Liu  阅读(3800)  评论(4编辑  收藏  举报
编辑推荐:
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· 展开说说关于C#中ORM框架的用法!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
点击右上角即可分享
微信分享提示