c# – 如何制作一个只读版本的类?

我有一个具有各种公共属性的类,我允许用户通过属性网格进行编辑.对于持久性,此类也通过DataContractSerializer序列化/反序列化到/从 XML文件.

有时候,我希望用户能够保存(序列化)他们对类的一个实例所做的更改.然而在其他时候,我不想允许用户保存他们的更改,而应该将属性网格中的所有属性看作只读.我不想允许用户进行更改,以后他们永远无法保存.类似于MS Word如何允许用户打开当前由其他人打开但仅作为只读的文档.

我的类有一个布尔属性,用于确定该类是否应该是只读的,但是可以使用此属性以某种方式在运行时将类只读属性动态添加到类属性中吗?如果不是什么替代解决方案?我应该将我的类包装在只读包装类中吗?

解决方法

不变性是C#仍有改进空间的领域.在创建具有只读属性的简单不可变类型的同时,一旦您需要更复杂的控制,当类型是可变的时,就开始运行到障碍物中.

您有三个选择,具体取决于您需要“强制执行”只读行为的强度:

>在你的类型中使用只读标志(就像你在做),让调用者负责不尝试更改类型上的属性 – 如果进行写入尝试,则抛出异常.
>创建一个只读接口,让你的类型实现它.这样,您可以通过该界面将类型传递给只应执行读取的代码.
>创建一个封装类,它聚合你的类型,只暴露读操作.

一个选项通常是最简单的,因为它可能需要对现有代码进行较少的重构,但为类型的作者提供最少的机会,以便在实例不可变时(而不是实例)通知消费者.此选项还提供了编译器在检测不当使用方面的最少支持,并将错误检测降级到运行时.

第二个选项很方便,因为实现一个接口是可能的,没有太多的重构努力.不幸的是,调用者仍然可以转换为底层类型并尝试针对它进行写入.通常,此选项与只读标志相结合,以确保不违反不变性.

第三个选项是执行过程中最强大的,但它可能导致代码重复,更多的是重构.通常,组合选项2和3是有用的,以使只读包装器和可变类型多态之间的关系.

就个人而言,在编写新的代码时,我倾向于使用第三个选项,我期望需要强制执行不变性.我喜欢这样一个事实:不可能“丢弃”不可变的包装器,它经常允许你避免在每个设置器中写入凌乱的if-read-throw-exception-exception检查.

相关文章

在要实现单例模式的类当中添加如下代码:实例化的时候:frmC...
1、如果制作圆角窗体,窗体先继承DOTNETBAR的:public parti...
根据网上资料,自己很粗略的实现了一个winform搜索提示,但是...
近期在做DSOFramer这个控件,打算自己弄一个自定义控件来封装...
今天玩了一把WMI,查询了一下电脑的硬件信息,感觉很多代码都...
最近在研究WinWordControl这个控件,因为上级要求在系统里,...