大咖直播-鸿蒙原生开发与智能提效实战!>>> 了解详情
写点什么

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

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

关注

评论

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

社区团购,拯救消费降级的利器

用友BIP

社区团购

DAPP智能合约双币质押挖矿项目系统开发

l8l259l3365

千帆大模型平台引领Falcon-180B适配创新

百度开发者中心

人工智能 Prompt 千帆大模型平台

当AI遇上3D建模:一场创意与技术的完美碰撞!

Finovy Cloud

AI 3D

云图说|交换数据空间Exchange Data Space

华为云开发者联盟

数据交换 开发 华为云 华为云开发者联盟

《永劫无间》新版本上线,英特尔锐炫及XeSS即时支持,助力玩家丝滑畅游!

E科讯

什么是智慧光伏?智慧光伏电站运维平台

2D3D前端可视化开发

物联网 数字孪生 三维可视化 智慧光伏 智慧电站

用大模型Prompt解决行业问题

百度开发者中心

大模型训练 Prompt

注释在编程中的重要性:理解程序员的两难选择

小魏写代码

ZGC关键技术分析

得物技术

Java 高性能 GC算法

最新开源、更擅长推理的中文大模型

百度开发者中心

人工智能 大模型

将 Amazon EC2 到 Amazon S3 的数据传输推向100Gbps 线速

亚马逊云科技 (Amazon Web Services)

S3 Amazon EC2 亚马逊云科技

不会写代码同学的福音——AI 代码生成器 Amazon CodeWhisperer(通过注释写代码)

亚马逊云科技 (Amazon Web Services)

人工智能 CodeWhisperer Amazon Lambda 云上探索实验室

IBM只有29%的职位看学历?基于技能的招聘到底是什么?

用友BIP

智能招聘

在Vue中使用Mock.js虚拟接口数据实例详解

树上有只程序猿

Vue Mock.js

中国水泥行业数字化采购:驱动产业链供应链现代化的关键

用友BIP

数智采购

Prompt模板助力应用升级

百度开发者中心

人工智能 大模型训练 Prompt

2个数仓中不等值关联优化案例

华为云开发者联盟

数据库 后端 华为云 数仓 华为云开发者联盟

平台工程动态 Monthly News 2023-9

杨振涛

DevOps 云原生 开发者体验 内部开发者平台 平台工程,

腾讯云入选2023 Gartner分布式混合基础设施魔力象限

极客天地

ABAQUS二次开发怎样接入Python代码?ABAQUS软件教程

思茂信息

abaqus abaqus软件 abaqus有限元仿真

大模型训练-实战的模型、算力与数据训练

百度开发者中心

人工智能 大模型训练

IDO官网预售 创建 ICO 解决方案:为您的代币发行奠定基础

区块链软件开发推广运营

交易所开发 dapp开发 区块链开发 链游开发 NFT开发

文末福利免费送 | KaiwuDB AI 时代数据库技术专题沙龙,名额仅剩 20 位,报名从速!

KaiwuDB

数据库 KaiwuDB

熟练使用 Redis 的五大数据结构:Java 实战教程

互联网工科生

Java redis

NFTScan 正式上线 Scroll NFTScan 浏览器和 NFT API 数据服务

NFT Research

NFT NFTScan nft工具

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