c# - 如何制作类(class)的只读版本?

标签 c# .net readonly-attribute

我有一个包含各种公共(public)属性的类,我允许用户通过属性网格对其进行编辑。为了持久化,此类还通过 DataContractSerializer 序列化/反序列化为 XML 文件。

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

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

最佳答案

不可变性是 C# 仍有改进空间的一个领域。虽然可以使用 readonly 属性创建简单的不可变类型,但一旦您需要更复杂地控制类型何时出现可变的,你开始遇到障碍。

根据您需要“强制”只读行为的强烈程度,您有三种选择:

  1. 在您的类型中使用只读标志(就像您正在做的那样)并让调用者负责不尝试更改类型的属性 - 如果进行了写入尝试,则抛出一个异常。

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

  3. 创建一个包装器类来聚合您的类型并仅公开读取操作。

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

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

就强制执行而言,第三种选择是最强的,但它可能导致代码重复,并且更像是一种重构工作。通常,将选项 2 和选项 3 结合起来很有用,可以使只读包装器和可变类型之间的关系成为多态的。

就我个人而言,在编写我希望需要强制执行不可变性的新代码时,我倾向于选择第三种选择。我喜欢这样一个事实,即不可能“丢弃”不可变包装器,并且它通常允许您避免在每个 setter 中编写困惑的 if-read-only-throw-exception 检查。

关于c# - 如何制作类(class)的只读版本?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2724731/

相关文章:

c# - 通过服务删除 Windows 登录屏幕

.net - HttpRequest.GetHashCode() 实现 - 冲突发生的频率如何?

c# - 如何在 ASP.NET MVC3 Razor 中创建只读文本框

c# - 为什么 Convert.ToString 格式会以这种方式加倍?

c# - 读取 tgz 归档文件而不保存/提取到磁盘

c# - 来自 EventHandler 的 Console.Writeline

android-studio - 安卓工作室 : Unable to add a new class or any file to a project

.net - 如何检测我的 C#/F# 代码在 Mono 或 .NET 上运行的平台?

c# - Azure 数据类型的本地结构和云处理之间的差异

c# - Visual Studio 不会使用 ReadOnlyAttribute(true) 使属性变灰