C# record的理解

目录

应用场景

为什么要用record而不用结构体

不适合的场景

不可变性

自定义构造方法和属性

解构

继承

值相等性

非破坏性变化

record class/readonly record struct/record struct

应用场景

  1. record可以用with关键字克隆出新的实体,而不是简单的引用传递。
  2. 如果两个实体是用record来声明的,那么可以比较两个实体的属性值是否都一致。
  3. 在进行实体输出时,如果该实体是用record声明的,那么输出的是该实体的内部数据结构,而不是一个类型的名称。

为什么要用record而不用结构体

  1. 为什么要用record而不用结构体,主要有三点原因。
  2. 第一个原因是因为结构体不支持继承。
  3. 第二个原因是因为结构体是值传递的过程,如果大量的结构体拥有着相同的数据,那么就会占用着不同的内存,导致内存浪费。
  4. 第三个原因是因为结构体的内部相等判断使用了ValueType.Equals方法,该方法是使用反射来实现的,因此性能不够快。

不适合的场景

record不适合在EFCore中使用,因为record重写了Equals方法和相等运算符(==和!=),这样可能会对EFCore的实体追踪机制造成影响。

不可变性

  1. record声明的实体具有不变性,因为该实体属性的setter是init,一旦初始化完成,它的属性值将不可修改。
  2. 虽然record声明的实体具有不可变性,但是可以通过自定义属性来覆盖原来的行为,让其属性变为可以修改。

自定义构造方法和属性

  1. record声明的实体在编译时会根据构造参数生成一个默认的构造函数,默认的构造函数不能被覆盖,如果有自定义的构造函数,那么需要使用this关键字来初始化这个默认的构造函数。
  2. record声明的实体中可以自定义属性,自定义属性名可以和构造参数名重名,也就是说自定义属性可以覆盖构造参数生成的属性,此时对应的构造参数将不起任何作用,但是可以通过属性指向这个构造参数来自定义这样一个属性。

解构

  1. record声明的实体在编译时会针对构造参数生成一个Deconstruct方法,用来支持解构。
  2. 解构只针对默认构造函数的构造参数。

继承

  1. record可以继承自record,但是record和类不能相互继承。
  2. 继承自record的子记录必须声明父记录中的各个参数。

值相等性

值相等性是值类型的一个概念,而record是引用类型,为了实现了值相等性,重写了Object的Equals和GetHashCode方法,重写了运算符==和!=,实现了IEquatable<T>接口。

非破坏性变化

  1. record声明的实体可以使用with关键字来实现非破坏性变化。
  2. 使用with关键字时会先调用<Clone>$()方法来创建一个对象,然后再对这个对象进行指定属性的初始 化。

record class/readonly record struct/record struct

  1. record class和readonly record struct生成的属性是get和init标识,也就是说它们的实体对象 是只读的。
  2. record struct生成的属性是get和set标识,也就是说它的对象是可读可写的。
  3. readonly record struct/record struct可以使用空构造函数初始化,可以不用with关键字进行克隆而直接 进行值复制。
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

木子丶鹏

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值