50万奖金+官方证书,深圳国际金融科技大赛正式启动,点击报名 了解详情
写点什么

简化 C#的不可变对象图

  • 2013-05-15
  • 本文字数:1070 字

    阅读完需:约 4 分钟

在 C#中创建一个简单的不可变类很容易,开发者只需要创建一个构造函数且不创建公共 setter。但这往往还不够。最终开发者或许会想要创建深层图,考虑到效率原因,应该通过建造者(builder)创建它。或者也许开发者想要创建一些方法,返回包含已变更字段的该对象的复本(如 DateTime 的 AddMinutes 方法),以此来实现非破坏性更新。构建全部这些建造者和方法非常冗长乏味,因此也容易出错。

Andrew L Arnott 提出了一个解决方案,它依靠基于 T4 的代码生成器。T4 代表“文本模版转换工具包”,Text Template Transformation Toolkit。它处于 Visual Studio 代码生成功能的核心位置,诸如实体框架等库都依赖它。Andrew 的 T4 脚本接收一个可变类并创建一个不可变的版本。

该工具包做出了一个略有争议的决定,即不生成公共构造器。相反,他期望开发者使用静态的 Create 方法,或是从 Default 实例开始然后修改它。这通过使用 WithXxx 方法实现,每个属性都有一个对应的方法。

不过,我们可以做更多的改进。对拥有许多属性的类,如果我们需要一次改变若干属性,那么在每个属性变更时都分配一个新对象作为中间步骤,将是一种浪费并且会增加 GC 的压力。因此我们还添加了一个 With 方法,为每个出现在类中的属性接收可选参数,从而支持属性的批量变更。最后,对于需要对对象进行多处变更,却又希望通过多个步骤实现(或者只是倾向于使用属性 setter 而不是调用 With- 方法)的场景,我们可以创建一个 Builder 类,它在构建过程中使用可变的类 ,并且将在完成后返回一个不可变复本。这一模式与.Net Framework 中的 String 和 StringBuilder 非常类似,也与之前提到过的最新不可变集合相似。

当然,如果开发者不喜欢这些决定,也可以很容易地修改 T4 模版。Andrew 故意将模版分解成更小的文件,从而让修改变得更容易。开发者还可以添加自己的扩展而无需对基础模版进行重大改变。

与所有良好编写的代码生成器相似,这里也大量使用了分部方法。分部方法允许开发者向代码生成器生成的方法中添加额外的逻辑,而不必修改生成的文件。例如,开发者可以实现一个类来为不可变对象设定部分默认值。未实现的分部方法将被编译器自动剥离出来,因此不会导致运行时开销。

开发者如果希望进一步了解 Arron 的实验,可以在他的博客中阅读关于不可变对象图的文章。

查看英文原文 Making Immutable Object Graphs Easier in C#


感谢姚琪琳对本文的审校。

给InfoQ 中文站投稿或者参与内容翻译工作,请邮件至 editors@cn.infoq.com 。也欢迎大家通过新浪微博( @InfoQ )或者腾讯微博( @InfoQ )关注我们,并与我们的编辑和其他读者朋友交流。

2013-05-15 09:272213
用户头像

发布了 256 篇内容, 共 86.3 次阅读, 收获喜欢 10 次。

关注

评论

发布
暂无评论
发现更多内容

ETL都没弄懂,谈什么大数据 ?我用一分钟给你整明白

智分析

ETL

Java中定时器Timer致命缺点(附学习方法)

叫练

学习 定时任务 多线程 定时器 技术学习

价值 - 价值的底色(一)

石云升

读书笔记 投资 28天写作 价值

要想软件“一想之美”,UI测试少不了

华为云开发者联盟

软件 测试 华为云

文档驱动开发模式在 AIMS 中的应用与实践

华为云开发者联盟

Web 代码 API 文档

volatile 关键字精讲

伯阳

Java volatile 后端 关键字 多线程与高并发

代码也能“杀”虫:此虫,真虫非Bug也

华为云开发者联盟

代码 华为云 modelarts

LeetCode题解:111. 二叉树的最小深度,BFS,JavaScript,详细注释

Lee Chen

算法 大前端 LeetCode

还在手动写数据库文档吗?试试这个工具,划水干活儿两不误!

我爱娃哈哈😍

数据库 文档生成

杜绝标题党,好的标题是成功的99%

xcbeyond

方法论 28天写作 写作技巧

开始的开始-可能是最早提交的28天写作活动作品

石君

28天写作

SpringCloud从入门到精通02---支付模块01

Felix

Hive的调优你都知道那些?

大数据老哥

大数据 hadoop hive

俯瞰Dubbo全局,阅读源码前必须掌握这些!!

冰河

架构 分布式 微服务 dubbo 服务治理

Spark HistoryServer日志解析&清理异常

kwang

大数据 spark hdfs

新思科技网络安全研究中心发现Bouncy Castle中的漏洞

InfoQ_434670063458

新思科技 Bouncy Castle

Kube-OVN 0.5.0 发布,支持 NetworkPolicy、用户自定义网卡和MTU

York

灵雀云 Kubernetes k8s Kube-OVN

大作业一:架构设计方案评审

Nick~毓

灵雀云Kube-OVN:基于OVN的开源Kubernetes网络实践

York

灵雀云 Kubernetes k8s Kube-OVN

如何使用Eclipse内存分析工具定位内存泄露

Java老k

Java 内存泄露

从七日更,到28天写作挑战,我无法拒绝的原因

梁龙先森

大前端 编程语言 28天写作

VUE项目性能优化实践——通过懒加载提升页面响应速度

葡萄城技术团队

Vue

软件界旷世之架:测试驱动开发(TDD)之争

华为云开发者联盟

软件 测试 TDD 代码 devcloud

SpringCloud从入门到精通01---父项目创建

Felix

SpringCloud Eureka 高可用架构

技术实录 | 灵雀云基于 OVN 的 Kubernetes 网络架构解析

York

灵雀云 Kubernetes k8s Kube-OVN

【CSS】CSS对大小写敏感吗?

德育处主任

28天写作

【Mysql-InnoDB系列】InnoDB架构

程序员架构进阶

MySQL 架构 innodb 28天写作

如果你听说过 Elastic Certified Engineer

escray

七日更 28天写作 死磕Elasticsearch 60天通过Elastic认证考试

一个正确的编程思维

程序员吴师兄

28天写作

边缘计算安全技术研究

华为云原生团队

云计算 大数据 云原生 边缘计算 华为云

云算力矿机租赁挖矿APP系统开发|云算力矿机租赁挖矿软件开发

系统开发

简化C#的不可变对象图_后端_Jonathan Allen_InfoQ精选文章