写点什么

在 C#6 和 VB 12 中不可变对象 (Immutable Objects ) 更易用

  • 2014-08-18
  • 本文字数:1211 字

    阅读完需:约 4 分钟

.NET 编程中的一个痛点: 为了实现不可变对象 (Immutable Objects ),需要编写大量样板代码。 不可变类 (immutable class) 不同于一个普通的类,它要求每个属性具有一个单独定义的字段,当然,还需要通过一个构造函数来填充每个字段的填。

根据新的规范草案,C#和 VB 将增加一个称为“记录类”(record class)的特性。实质上, 它是仅由在构造函数中定义的不可变类 (immutable class)。

下面是规范的一行代码示例:

public record class Cartesian(double x: X, double y: Y);除了这个构造函数外,编译器会自动创建:

  • 生成每个参数的只读属性(read-only property)
  • 生成 Equals 函数
  • 重写 GetHashCode 函数
  • 重写 ToString 函数
  • 生成一个“is”操作符,在 VB 中称为“Matches”

“is/Matches”操作符被用于模式匹配 (pattern matching),我们会在未来的文章涉及到。除此之外,记录类(record classes)和 C#匿名类型(anonymous types)很相近(和 VB 的匿名类型有所不同,它们默认是可变的)。对这两种概念,微软正研究如何协调,尤其是基于现有的程序集中,还不能对外暴露匿名类型接口。

不可变类型的一个通用特性是在对对象的一个或多个字段进行改变后,会自动产生当前对象的拷贝。虽然在规范中没有提到,但微软正在考虑为 C#提供如下方式作为一种选项:

复制代码
var x1 = new MyRecord(1, 2, 3);
var x2 = x1 with B: 16;
Console.WriteLine(x2) // prints something like "A = 1, B = 16, C = 3"

扩展记录类

你可能已经注意到,在 Cartesian 示例类中,用分号表示结束。表明该类不包含任何类体,只保留由编译器负责自动生成提供的那部分。

除了直接使用分号结束定义,你还可以像一个普通的类一样,通过提供一组大括号,并添加其他属性和方法。编译后,你仍然会得到编译器自动生成的代码。

其他限制

目前还暂时只支持记录类(record classes)。在理论上,也能够使用相同的基本语法和概念进行添加记录结构体(record structs)。

类库支持问题

在.NET 中使用不可变类型(immutable types)有一个严重的限制,即它缺乏广泛的类库支持。想象一下,如果你是一个负责中间层的开发者,那你每日的工作很可能就是通过 ORM 从数据库获取一些对象,然后再序列化到 SOAP-XML 或 JSON,然后以单向或者双向的方式传递给客户端。

但是, 目前的大多数的 ORM 及序列化支持不可变类型(immutable types),它们会假定该类型具有一个无参数的构造函数,并且包含一些可变的属性。如果这个问题没有在这些流行的框架中解决,那么在大多数工程项目中记录类(record classes)将用处不大。

欲了解更多信息,请参见草案规范 Pattern Matching for C#。该原型应该可以在数周内发布。

查看原文链接: Easier Immutable Objects in C# 6 and VB 12


感谢邵思华对本文的审校。

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

2014-08-18 01:502021
用户头像
王文刚 Instagram 营销专家

发布了 37 篇内容, 共 27.1 次阅读, 收获喜欢 55 次。

关注

评论

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

在线ASCII流程图编辑器工具

入门小站

工具

云端开发在阿里的典型应用场景 | 阿里巴巴DevOps实践指南

阿里云云效

阿里云 云原生 云平台 研发工具 云端开发

无障碍读屏出错了

admin

小程序 性能优化 瀑布流 relations 无障碍

一个人手写APP监控平台是什么体验 | 社区征文

一诺倾心

flutter android 性能优化 APM

Linux之vmstat命令

入门小站

Linux

拒绝做工具小子—编写Python漏洞验证脚本

网络安全学海

黑客 网络安全 信息安全 渗透测试 安全漏洞

产品经理角色理解

wood

300天创作

领域模型设计该如何落地到数据库设计?

蜜糖的代码注释

Java DDD 领域模型 2月月更

BIGO 使用 Flink 做 OLAP 分析及实时数仓的实践和优化

Apache Flink

大数据 flink 编程 后端 实时计算

react源码解析3.react源码架构

buchila11

React

关于如何构建 Go 代码的思考

宇宙之一粟

Go 语言 2月月更

TiDB 在国信证券海量数据高并发场景中的实践

陈培新

TiDB

Web Components系列(三) —— 创建 Custom Elements

编程三昧

前端 组件化 2月月更 WebContents

推荐 3 个 React 动画库

devpoint

React 网页动画 2月月更

mysql 面试总结

yuexin_tech

面试

王者荣耀商城异地多活设计

皓月

「架构实战营」

不会用SpringBoot连接Redis,那就赶紧看这篇

华为云开发者联盟

redis 开发 springboot Redis服务器

运维与微服务结合?深度解析微服务框架Tars整体解决方案

云智慧AIOps社区

DevOps 微服务 运维 云原生 TARS

AI+Science:基于飞桨的AlphaFold2,带你入门蛋白质结构预测

百度大脑

在线学习FTRL介绍及基于Flink实现在线学习流程|社区征文

张浩_house

机器学习 大数据 flink 新春征文

RTE2021 回顾丨HDR 技术产品实践与探索

RTE开发者社区

人工智能 HDR

设计模式【13】-- 模板模式怎么弄?

秦怀杂货店

Java 设计模式 23种设计模式

我的云原生学习方法 | 社区征文

大菠萝

新春征文

网络安全kali渗透学习 web渗透入门 Google搜索引擎的使用技巧

学神来啦

B站员工猝死,审核员之殇,谁该反省?谁该惭愧?技术层面解构内容安全审核系统(python3)

刘悦的技术博客

系统架构 内容审核 Python3 应用审核 构架

一起玩转LiteOS组件:Pixman

华为云开发者联盟

LiteOS LiteOS组件 Pixman Pixman Demo LiteOS组件仓库

【架构训练营-模块二】

默光

微信朋友圈 架构训练营5期

一文搞明白直播和点播的区别 | 社区征文

liuzhen007

音视频 新春征文 2月月更

AI象棋,谁与争锋

乌龟哥哥

AI 2月月更

一文带你了解数仓智能运维框架

华为云开发者联盟

运维 GaussDB(DWS) 智能运维框架 调度框架 任务调度器

在C#6和VB 12中不可变对象(Immutable Objects )更易用_C#_Jonathan Allen_InfoQ精选文章