如何制作课程的只读版本? [英] How can I make a read only version of a class?

查看:112
本文介绍了如何制作课程的只读版本?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个带有各种公共属性的类,允许用户通过属性网格进行编辑。为了持久化,该类还可以通过DataContractSerializer序列化到XML文件或从XML文件反序列化。



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



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

解决方案

不可移植性是C#仍有空间的领域。虽然可以使用 readonly 属性创建简单的不可变类型,但是一旦需要对类型何时可变的更复杂的控制,您就会遇到障碍。 p>

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


  1. 在您的类型中使用一个只读标志(就像您正在做的那样),并让调用方负责不尝试更改类型的属性-如果尝试写入完成后,引发异常。


  2. 创建一个只读接口,并让您的类型实现它。这样,您可以通过该接口将类型传递给只应执行读取操作的代码。


  3. 创建一个包装类,用于汇总您的类型,并且只公开读取操作。


第一个选项通常是最简单的,因为它可以要求对现有代码的重构较少,但是类型的创建者在实例不可变与实例不可变时通知消费者的机会最少。此选项还为编译器提供了最少的支持,可用于检测不当使用-并将错误检测委托给运行时。



第二个选项很方便,因为无需使用接口即可实现接口大量的重构工作。不幸的是,调用者仍然可以转换为基础类型并尝试对其进行写入。通常,此选项与只读标志结合使用以确保不违反不变性。



就执行而言,第三个选项是最强的,但是它可能导致代码重复,并且需要更多的重构工作。通常,结合使用选项2和3,以使只读包装程序与可变类型多态性之间的关系很有用。



我个人倾向于在编写我希望需要实现不可变性的新代码时,请选择第三个选项。我喜欢这样的事实,即无法舍弃不可变的包装器,并且它通常使您避免编写混乱的if-read -throw-exception检查每个设置器。


I have a class with various public properties which I allow users to edit through a property grid. For persistence this class is also serialized/deserialized to/from an XML file through DataContractSerializer.

Sometimes I want to user to be able to save (serialize) changes they've made to an instance of the class. Yet at other times I don't want to allow the user to save their changes, and should instead see all the properties in the property grid as read only. I don't want to allow users to make changes that they'll never be able to save later. Similar to how MS Word will allow users to open documents that are currently opened by someone else but only as read only.

My class has a boolean property that determines if the class should be read-only, but is it possible to use this property to somehow dynamically add a read-only attributes to the class properties at run-time? If not what is an alternative solution? Should I wrap my class in a read-only wrapper class?

解决方案

Immutability is an area where C# still has room to improve. While creating simple immutable types with readonly properties is possible, once you need more sophisticated control over when type are mutable you start running into obstacles.

There are three choices that you have, depending on how strongly you need to "enforce" read-only behavior:

  1. Use a read-only flag in your type (like you're doing) and let the caller be responsible for not attempting to change properties on the type - if a write attempt is made, throw an exception.

  2. Create a read-only interface and have your type implement it. This way you can pass the type via that interface to code that should only perform reads.

  3. Create a wrapper class that aggregates your type and only exposes read operations.

The first option is often the easiest, in that it can require less refactoring of existing code, but offers the least opportunity for the author of a type to inform consumers when an instance is immutable vs when it is not. This option also offers the least support from the compiler in detecting inappropriate use - and relegates error detection to runtime.

The second option is convenient, since implementing an interface is possible without much refactoring effort. Unfortunately, callers can still cast to the underlying type and attempt to write against it. Often, this option is combined with a read-only flag to ensure the immutability is not violated.

The third option is the strongest, as far as enforcement goes, but it can result in duplication of code and is more of a refactoring effort. Often, it's useful to combine option 2 and 3, to make the relationship between the read-only wrapper and the mutable type polymorphic.

Personally, I tend to perfer the third option when writing new code where I expect to need to enforce immutability. I like the fact that it's impossible to "cast-away" the immutable wrapper, and it often allows you to avoid writing messy if-read-only-throw-exception checks into every setter.

这篇关于如何制作课程的只读版本?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆