QCon 演讲火热征集中,快来分享技术实践与洞见! 了解详情
写点什么

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

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

关注

评论

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

webrtc Fec kPacketMaskRandomTbl 概述

webrtc developer

webrtc、 fec mask

2021 CHIMA观感:医疗信息化发展的几个趋势,值得关注

菜根老谭

医疗信息化

理解RESTful API

林十二XII

什么是CPython

林十二XII

不是吧 阿sir!都21年了还有人不会算法?赠你份字节内部算法手册吧

Java 编程 架构 面试 架构师

面试官:你说说限流的原理?

艾小仙

面试

拯救你的算法!GitHub上神仙项目手把手带你刷算法,Star数已破110k

Java 编程 架构 面试 程序人生

少女银四失足,偶得“阿里Java神级题库(25专题)”,金九稳了

公众号_愿天堂没有BUG

Java 编程 程序员 架构 面试

来自阿里的图解计算机、网络、操作系统PDF,竟在GitHub点赞最高

公众号_愿天堂没有BUG

Java 编程 程序员 架构 面试

高能预警!Alibaba最新出版的JDK源码剖析手册(究极奥义版)开源

Java 程序员 架构 面试 Alibaba

ironSource 出品 AdQuality 解决方案全新升级,助力开发者管理应用内广告

常见的IT自动化运维工具有哪些?推荐一款好用的?

行云管家

阿里云 运维 IT运维 PSSH

过二级等保需要哪些安全设备?多少钱?

行云管家

数据库 网络安全 等保 等级保护

Redis缓存那点破事 | 绝杀面试官 25 问!

Java redis 架构 后端 计算机

字节大佬的「算法界Offer收割机」火爆Github,短时间获上万star

公众号_愿天堂没有BUG

Java 编程 程序员 架构 面试

在?来说点儿程序员Style的金句吧【话题讨论】

气气

话题讨论

腾讯出品526页异步非阻塞通信领域巅峰之作:Netty IO核心技术指南

公众号_愿天堂没有BUG

Java 编程 程序员 架构 面试

偷偷翻开学妹笔记本,发现绝密Spring Cloud Alibaba笔记

公众号_愿天堂没有BUG

Java 编程 程序员 架构 面试

牛掰!阿里大佬刷了四年LeetCode才总结出来的数据结构和算法手册

Java 编程 架构 面试 程序人生

在云中确保安全的五个技巧

云计算

使用DEM和矢量数据绘制地图

gisbook

GIS map DEM

无敌!肝完这套Alibaba面试全能小册,百万年薪在向你招手!

Java 阿里巴巴 编程 面试 程序人生

FunTester测试框架Redis性能测试实践

FunTester

redis 性能测试 测试框架 FunTester

MySQL连接控制插件介绍

Simon

MySQL

原地起飞!字节工程师开源了GitHub的Java开发百宝手册后,被骂哭

公众号_愿天堂没有BUG

Java 编程 程序员 架构 面试

网易24周年,竟拿出内部进阶必备的网络协议笔记,给程序员发福利

公众号_愿天堂没有BUG

Java 编程 程序员 架构 面试

在 CentOS 7上安装Sonatype Nexus Repository OSS

吴脑的键客

nexus Ops

【万字干货】OpenMetric与时序数据库存储模型分析

华为云开发者联盟

OLAP 时序数据库 index Metric Timeseries

阿里最受追捧的「中高级技术核心」,助我拿下菜鸟offer,附面经

公众号_愿天堂没有BUG

Java 编程 程序员 架构 面试

火爆全网的Spring Security手册及源码笔记,在Github上标星103K

编程 架构 面试 程序人生 金九银十

工信部整治平台网址屏蔽问题,打击互联网行业垄断任重道远

石头IT视角

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