C#中的记录类型(record)是什么 - C# 9.0带来的不可变数据模型
发布时间 - 2026-01-01 00:00:00 点击率:次record是C# 9.0引入的引用类型,专为不可变、值语义明确的数据模型设计,支持值相等、init属性、with表达式和位置语法,适用于DTO、配置项等场景。
记录类型(record)是C# 9.0引入的一种引用类型,专为表示不可变、值语义明确的数据模型而设计。它不是类的替代品,而是针对“数据载体”场景做了语法和语义优化:默认按值比较、自动生成相等逻辑、支持位置语法和with表达式,让数据建模更简洁、安全、不易出错。
记录类型的核心特性
record本质仍是类(class),但编译器为其注入了关键行为:
-
值相等性(Value Equality):两个record实例只要所有公开属性/字段的值相同,就视为相等(
==和.Equals()自动生效),无需手动重写; -
不可变性(Immutability by Convention):推荐使用
init访问器声明属性(只能在构造或对象初始化器中赋值),编译器禁止后续修改; -
非破坏性变异(Non-destructive Mutation):通过
with表达式可创建新实例并修改部分属性,
原实例保持不变(如 person with { Age = 30 }); -
位置记录(Positional Records):用
record Person(string Name, int Age);语法可自动生成构造函数、只读属性、Deconstruct方法,支持解构和模式匹配。
record与class的关键区别
虽然record编译后仍是class,但语义差异明显:
- class默认按引用相等,record默认按值相等;
- class的属性通常用
get; set;,易被意外修改;record鼓励get; init;,天然防御性更强; - class需手动实现
ToString()、GetHashCode()、Equals()才能正确支持数据场景;record全部自动生成; - record支持继承(可声明
sealed或派生),但基record的with表达式会正确处理派生类型(C# 10起增强)。
何时该用record而不是class
适合用record的典型场景:
- DTO(数据传输对象)、API响应模型、配置项、查询结果封装;
- 需要频繁比较是否“内容相同”的数据结构(如缓存键、测试断言);
- 函数式风格编程,强调无副作用和不可变数据流;
- 配合模式匹配(
switch表达式)做数据解构和分支处理。
不适合的场景:需要频繁修改内部状态、依赖事件通知、有复杂生命周期管理的对象——这类仍应使用class。
一个实用示例
定义一个订单项记录:
record OrderItem(string ProductName, decimal Price, int Quantity){
public decimal Total => Price * Quantity;
}
使用起来很轻量:
var item1 = new OrderItem("Laptop", 999.99m, 1);-
var item2 = item1 with { Quantity = 2 };→ 新实例,item1不变 -
if (item1 == item2) ...→ 比较的是值,不是引用 -
var (name, price, qty) = item1;→ 自动解构,无需额外代码
基本上就这些。record不是银弹,但它让“只关心数据是什么”的代码变得更清晰、更健壮、更少 boilerplate。
# switch
# 区别
# c#
# String
# if
# 封装
# 构造函数
# 派生类型
# int
# 数据结构
# 继承
# class
# 引用类型
# public
# 访问器
# var
# 对象
# 事件
# 自动生成
# 仍是
# 专为
# 的是
# 推荐使用
# 适用于
# 这类
# 为其
# 重写
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
如何在IIS中新建站点并配置端口与IP地址?
如何快速配置高效服务器建站软件?
Laravel怎么集成Log日志记录_Laravel单文件与每日日志配置及自定义通道【详解】
logo在线制作免费网站在线制作好吗,DW网页制作时,如何在网页标题前加上logo?
,网页ppt怎么弄成自己的ppt?
JS中页面与页面之间超链接跳转中文乱码问题的解决办法
Laravel表单请求验证类怎么用_Laravel Form Request分离验证逻辑教程
b2c电商网站制作流程,b2c水平综合的电商平台?
独立制作一个网站多少钱,建立网站需要花多少钱?
java ZXing生成二维码及条码实例分享
laravel服务容器和依赖注入怎么理解_laravel服务容器与依赖注入解析
学生网站制作软件,一个12岁的学生写小说,应该去什么样的网站?
电商网站制作多少钱一个,电子商务公司的网站制作费用计入什么科目?
如何快速搭建高效香港服务器网站?
标题:Vue + Vuex + JWT 身份认证的正确实践与常见误区解析
如何用JavaScript实现文本编辑器_光标和选区怎么处理
如何快速建站并高效导出源代码?
奇安信“盘古石”团队突破 iOS 26.1 提权
Python自然语言搜索引擎项目教程_倒排索引查询优化案例
如何用虚拟主机快速搭建网站?详细步骤解析
七夕网站制作视频,七夕大促活动怎么报名?
Laravel API路由如何设计_Laravel构建RESTful API的路由最佳实践
如何在自有机房高效搭建专业网站?
北京网页设计制作网站有哪些,继续教育自动播放怎么设置?
JavaScript如何实现错误处理_try...catch如何捕获异常?
什么是JavaScript解构赋值_解构赋值有哪些实用技巧
使用Dockerfile构建java web环境
详解jQuery中基本的动画方法
如何选择PHP开源工具快速搭建网站?
php结合redis实现高并发下的抢购、秒杀功能的实例
PHP的CURL方法curl_setopt()函数案例介绍(抓取网页,POST数据)
如何实现建站之星域名转发设置?
Laravel如何使用Telescope进行调试?(安装和使用教程)
Laravel如何集成微信支付SDK_Laravel使用yansongda-pay实现扫码支付【实战】
Android仿QQ列表左滑删除操作
JavaScript Ajax实现异步通信
如何在腾讯云服务器上快速搭建个人网站?
Linux系统命令中tree命令详解
Laravel怎么处理异常_Laravel自定义异常处理与错误页面教程
如何在IIS中新建站点并解决端口绑定冲突?
详解一款开源免费的.NET文档操作组件DocX(.NET组件介绍之一)
html5audio标签播放结束怎么触发事件_onended回调方法【教程】
百度输入法ai组件怎么删除 百度输入法ai组件移除工具
Laravel如何配置和使用缓存?(Redis代码示例)
宙斯浏览器怎么屏蔽图片浏览 节省手机流量使用设置方法
JavaScript如何实现继承_有哪些常用方法
Laravel如何使用Gate和Policy进行权限控制_Laravel权限判定与策略规则配置
如何制作一个表白网站视频,关于勇敢表白的小标题?
北京网站制作费用多少,建立一个公司网站的费用.有哪些部分,分别要多少钱?
ChatGPT怎么生成Excel公式_ChatGPT公式生成方法【指南】


原实例保持不变(如