一、记录(record)C# 9.0 引入了记录类型 。可使用 record
关键字定义一个引用类型,以最简的方式创建不可变类型 。这种类型是线程安全的,不需要进行线程同步,非常适合并行计算的数据共享 。它减少了更新对象会引起各种bug的风险,更为安全 。System.DateTime 和 string 也是不可变类型非常经典的代表 。
与类不同的是 , 它是基于值相等而不是唯一的标识符--对象的引用 。
通过使用位置参数或标准属性语法,可以创建具有不可变属性的记录类型,整个对象都是不可变的,且行为像一个值 。
优点:
??1)在构造不可变的数据结构时,它的语法简单易用;
??2)record 为引用类型,不用像值类型在传递时需要内存分配 , 还可整体拷贝;
??3)构造函数和结构函数为一体的、简化的位置记录;
??4)有力的相等性支持 —— 重写了 Equals(object), IEquatable, 和 GetHashCode() 这些基本方法 。
record 类型可以定义为可变的,也可以是不可变的 。
// 没有 set 访问器,创建后不可更改,叫不可变类型public record Person{// 要支持用对象初始化器进行初始化,则在属性中使用 init 关键字// 或者以构造函数的方式public string? FirstName { get; init; }public string? LastName { get; init; }}// 可变类型的 record// 因为有 set 访问器,所以它支持用对象初始化器进行初始化public record Person{public string? FirstName { get; set; }public string? LastName { get; set; }}
记录(record)和类一样,在面向对象方面,支持继承 , 多态等所有特性 。除过前面提到的 record 专有的特性,其他语法写法跟类也是一样 。同其他类型一样,record 的基类依然是 object 。
??注意:1)记录只能从记录继承 , 不能从类继承,也不能被任何类继承; 2)record 不能定义为 static 的 , 但是可以有 static 成员 。
从本质上来讲,record 仍然是一个类,但是关键字 record 赋予这个类额外的几个像值的行为:
??1)基于值相等性的比较方法,如 Equals,==,!=,EqualityContract 等; 2)重写 GetHashCode(); 3)拷贝和克隆成员; 4)PrintMembers 和 ToString() 方法 。
应用场景:
??1)用于 web api 返回的数据,通常作为一种一次性的传输型数据,不需要是可变的,因此适合使用 record;2)作为不可变数据类型 record 对于并行计算和多线程之间的数据共享非常适合,安全可靠;3)record 本身的不可变性和 ToString 的数据内容的输出 , 不需要人工编写很多代码,就适合进行日志处理;4)其他涉及到有大量基于值类型比较和复制的场景,也是 record 的常用的使用场景 。
with 表达式??当使用不可变的数据时,一个常见的模式是从现存的值创建新值来呈现一个新状态 。
??例如,如果 Person 打算改变他的姓氏(last name),我们就需要通过拷贝原来数据,并赋予一个不同的 last name 值来呈现一个新 Person 。这种技术被称为非破坏性改变 。作为描绘随时间变化的 person,record 呈现了一个特定时间的 person 的状态 。为了帮助进行这种类型的编程,针对 records 就提出了 with 表达式,用于拷贝原有对象,并对特定属性进行修改
// 修改特定属性后复制给新的 recordvar person = new Person { FirstName = "Mads", LastName = "Nielsen" };var otherPerson = person with { LastName = "Torgersen" };// 只是进行拷贝,不需要修改属性 , 那么无须指定任何属性修改Person clone = person with { };
??with 表达式使用初始化语法来说明新对象在哪里与原有对象不同 。with 表达式实际上是拷贝原来对象的整个状态值到新对象,然后根据对象初始化器来改变指定值 。这意味着属性必须有 init 或者 set 访问器 , 才能用 with 表达式进行更改 。
??注意:1)with 表达式左边操作数必须为 record 类型; 2)record 的引用类型成员,在拷贝的时候,只是将所指实例的引用进行了拷贝 。
推荐阅读
- 地铁跑酷怎么加好友
- iPhone13pro和13promax怎么选_区别对比
- 华硕灵耀Pro14和小新pro16有什么区别_华硕灵耀Pro14和小新pro16怎么选择
- 手机QQ怎么截图和发送(qq怎么上传截图)
- Ubuntu 下安装 redis 并且设置远程登陆和密码
- iqoo7和iqoo5pro对比_iqoo7和iqoo5pro怎么选
- 一 Pthread 并发编程——深入剖析线程基本元素和状态
- realmeGT大师探索版和红米K40区别对比_哪款更值得买
- 华为p50和荣耀50哪个好_华为p50和荣耀50有什么区别
- 骁龙778g和麒麟990哪个好_骁龙778g和麒麟990处理器对比