阿里、蚂蚁、晟腾、中科加禾精彩分享 AI 基础设施洞见,现购票可享受 9 折优惠 |AICon 了解详情
写点什么

简化 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:271644
用户头像

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

关注

评论

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

阿里表哥甩我一份Redis笔记,看完还进不了阿里让我卖豆腐去

做梦都在改BUG

Java 数据库 nosql redis 缓存

抽丝剥茧还原真相,记一次神奇的崩溃

阿里技术

debug

GitHub 润色框架,让你的GitHub不再索然无味

做梦都在改BUG

GitHub

海泰方圆又双叒叕连获两项隐私计算专利

电子信息发烧客

2023年10大主流产品路线图绘制软件盘点

PingCode

产品经理 产品路线图工具

YOWOv2:优秀的实时视频动作检测框架

Zilliz

计算机视觉 构建模型 Milvus

传统企业,如何构建性能测试技术体系

老张

技术 #性能测试

常用MQTT客户端库简介

EMQ映云科技

物联网 IoT mqtt 客户端 企业号 3 月 PK 榜

华为云视频直播,流量大放“价”,超好用!

科技怪授

以“业财合一”构建业务财务体系,让财务更在行,让业务会经营

用友BIP

iOS上架App Store详解(图文)

雪奈椰子

全网超火Blender零基础教程!从零上手的免费3D软件

Finovy Cloud

blender 3D软件

代码开源!阿里妈妈展示广告Match底层技术架构最新进展

阿里技术

开源

如何通过优化图片、JS等资源加载项来提高网页的加载速度?

兴科Sinco

前端开发 CDN HTTP 网页加速

DevOps|研发效能不是老板工程,是开发者服务

laofo

DevOps cicd 研发效能 持续交付 平台工程

国有企业财务数智化转型实践,用友BIP一路随行

用友BIP

财务数智化

强!阿里P9限时开源的实战笔记:SpringBoot2精髓

做梦都在改BUG

Java 面试 微服务 Spring Boot 框架

Kubernetes玄幻问题一览

陆云

#Kubernetes#

Copilot 用“粉紫色磨砂UI”和“啊啊啊BGM ”,梦境了这届网友

B Impact

牧云助手:一款面向技术爱好者的远程主机管理工具

百川云开发者

运维 主机管理 终端远程协助

ios开发者账号到期了如何续费(详细步骤)

雪奈椰子

这是我见过最好的JVM笔记,拿到阿里offer后我哭了

做梦都在改BUG

Java JVM 虚拟机 垃圾回收

面试官:String字符串的最大长度是多少?

做梦都在改BUG

Java

“AI 上运动,直播更精彩” 百度智能云联手 Pixellot 创新中国大众体育传播新模式

Baidu AICLOUD

视频云 云导播

强大的录屏:Camtasia 2022 汉化激活版

真大的脸盆

Mac 软件 屏幕录制 录屏软件 录屏工具

测试人社区——软件测试技术沙龙分享

测试人

人工智能 软件测试 精准测试 工程效能 ChatGPT

云智一体,深入生命科学

Baidu AICLOUD

基因测序 AI制药 AI for Science

五大方面多管齐下,用友助力企业建设世界一流司库体系

用友BIP

《深入理解高并发编程:JDK核心技术》-冰河新书上市

冰河

并发编程 多线程 高并发 协程 异步编程

携手共进丨九科信息入选信通院“铸基计划”高质量数字化转型产品及服务全景图,并受邀出席高质量数字转型创新大会

九科Ninetech

焱融科技荣登《2022中国企业数智化创新TOP50》榜单

焱融科技

文件存储 分布式文件存储 数智化 高性能存储 全闪存储

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