报名参加CloudWeGo黑客松,奖金直推双丰收! 了解详情
写点什么

在 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:501666
用户头像
王文刚 Instagram 营销专家

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

关注

评论

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

创新公司iLabService 释普科技启示录

B Impact

独家巨献!阿里技术专家兼Github贡献者,整理的Spring Security入门到成神

Geek_0c76c3

Java 数据库 开源 程序员 开发

软件测试 | 测试开发 | Google 测试总监聊如何经营成功的测试职业生涯

测吧(北京)科技有限公司

测试

Flowable 中 ReceiveTask 怎么玩?

江南一点雨

Java springboot workflow flowable JavaEE

两将军问题和TCP三次握手

有态度的马甲

TCP协议 两将军问题

C语言中的内存模型

C++后台开发

内存模型 C语言 C/C++ linux开发 C++开发

【一Go到底】第九天---进制

指剑

Go golang 10月月更

DAG 任务调度与 go-streams 结合的应用实践

KaiwuDB

如何从InfluxDB/OpenTSDB无缝连接到TDengine

TDengine

数据库 tdengine 开源 时序数据库

Google 发布:DevOps 2022现状报告

SEAL安全

DevOps 研发效能 软件交付 软件供应链

你好,广州!openGauss广州用户组招募计划正式开启

《编程的原则》读书笔记(二): 编程理论的三个思想和六个实现原则

Chares

软件工程 软件开发 编程原理 软件开发原则

Vue网站自动提交百度链接

源字节1号

软件开发 后端开发 Vue网站

如何优雅地编写一个高逼格的JS插件?

茶无味的一天

JavaScript 前端 js JS插件

如何快速打造BI大屏进行数据赋能

力软低代码开发平台

SQL抽象语法树及改写场景应用

京东科技开发者

sql SQL优化 场景应用 SQL语言 抽象语法树

大数据ELK(十九):使用FileBeat采集Kafka日志到Elasticsearch

Lansonli

Filebeat 10月月更

GitLab + Jenkins + Harbor 工具链快速落地指南

胡说云原生

DevOps gitlab cicd Harbor jenkins

Zebec即将推出公链并开放节点申请,潜力几何?

西柚子

智能合约系统开发Web3.0实现核心

薇電13242772558

智能合约

具有资质的昆明等保测评公司新名单看这里!

行云管家

等保 堡垒机 等级保护

10分钟开发Kubernetes Operator

俞凡

架构 Kubernetes 云原生

32天高效突击:狂刷《Java权威面试指南(阿里版)》,offer拿到手软!

Geek_0c76c3

Java 数据库 开源 程序员 开发

软件测试 | 测试开发 | Java or Python?测试开发工程师如何选择合适的编程语言?

测吧(北京)科技有限公司

测试

【荣耀帐号服务FAQ】AuthorizationCode有效期是多久?

荣耀开发者服务平台

手机 服务 安卓 荣耀 honor

【iOS逆向】某运营商签名算法分析

小陈

逆向思维 逆向 iOS逆向 逆向分析

ESP32-C3 应用程序的启动流程

矜辰所致

ESP32-C3 10月月更 ESP-IDF

干货|仅需3步完成酷炫数据可视化大屏制作!

云智慧AIOps社区

大前端 低代码 数据可视化 智慧大屏可视化 可视化大屏

旺链科技入选2022“科创中国”创新成果名单

旺链科技

区块链 金融科技 产业区块链

易操作、可观测、可扩展,EMQX如何简化物联网应用开发

EMQ映云科技

运维 物联网 IoT emqx 10月月更

网络安全漏洞分析之远程代码执行

网络安全学海

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

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