record关键字定义引用类型
C# 9.0引入了新的特性“Record types”,为封装数据提供了内置的功能。本文将详细讨论如何在C# 9.0中使用Record types,并提供示例。
# 什么是Record types?
Record types是设计用于存储数据的引用类型。它们可以使用位置参数或标准属性语法创建不可变的属性。Record types类似于类,但它们提供了一些内置的功能,例如:
- 基于值的相等性
- 基于值的哈希
- 一个
ToString
方法,打印所有属性的值 - 一个构造函数,接受并初始化所有属性
- 一个
with
表达式,用于创建具有更新值的记录的新实例
虽然记录可以是可变的,但它们主要用于支持不可变的数据模型。 记录类型提供以下功能:
- 用于创建具有不可变属性的引用类型的简明语法
- 行为对于以数据为中心的引用类型非常有用:
- 值相等性
- 非破坏性变化的简明语法
- 用于显示的内置格式设置
- 支持继承层次结构
可使用结构类型来设计以数据为中心的类型,这些类型提供值相等性,并且很少或没有任何行为。 但对于相对较大的数据模型,结构类型有一些缺点:
- 它们不支持继承。
- 它们在确定值相等性时效率较低。 对于值类型,ValueType.Equals 方法使用反射来查找所有字段。 对于记录,编译器将生成 Equals 方法。 实际上,记录中的值相等性实现的速度明显更快。
- 在某些情况下,它们会占用更多内存,因为每个实例都有所有数据的完整副本。 记录类型是引用类型,因此,记录实例只包含对数据的引用。
# 创建Record types
要创建Record types,您需要使用 record
关键字,后跟记录类型的名称。以下是一个简单的Record类型的示例:
record Person(string FirstName, string LastName);
在此示例中,我们定义了一个名为 Person
的记录类型,它有两个属性:FirstName
和 LastName
。我们可以像这样创建这个Record类型的实例:
var person = new Person("John", "Doe");
# 位置参数
Record types可以使用位置参数创建具有不可变属性的记录类型。以下是一个具有三个属性的Record类型的示例:
record Point(int X, int Y, int Z);
在此示例中,我们定义了一个名为 Point
的Record类型,它有三个属性:X
、Y
和 Z
。我们可以像这样创建这个Record类型的实例:
var point = new Point(1, 2, 3);
# 标准属性语法
Record types也可以使用标准属性语法创建具有不可变属性的Record类型。以下是具有两个属性的Record类型的示例:
record Car
{
public string Make { get; }
public string Model { get; }
public Car(string make, string model)
{
Make = make;
Model = model;
}
}
在此示例中,我们定义了一个名为 Car
的Record类型,它有两个属性:Make
和 Model
。我们可以像这样创建这个Record类型的实例:
var car = new Car("Honda", "Civic");
# 相等性和哈希
Record types提供基于值的相等性和哈希。这意味着,如果两个Record类型的实例的属性具有相同的值,则它们被认为是相等的。以下是具有两个属性的Record类型的示例:
record Person(string FirstName, string LastName);
我们可以创建两个Record类型的实例:
var person1 = new Person("John", "Doe");
var person2 = new Person("John", "Doe");
如果我们使用 ==
运算符比较这些实例,则结果将为 true
:
Console.WriteLine(person1 == person2); // 输出: True
Record类型的 GetHashCode
方法是根据其属性的值自动实现的。以下是一个示例:
Console.WriteLine(person1.GetHashCode()); // 输出: 350355203
Console.WriteLine(person2.GetHashCode()); // 输出: 350355203
两个实例具有相同的哈希代码,因为它们具有相同的属性值。
# 更新记录
Record types提供 with
表达式,用于创建具有更新值的Record的新实例。以下是具有两个属性的Record类型的示例:
record Person(string FirstName, string LastName);
我们可以创建一个Record类型的实例:
var person1 = new Person("John", "Doe");
要更新这个Record类型的实例,我们可以使用 with
表达式:
var person2 = person1 with { LastName = "Smith" };
在此示例中,我们使用 with
表达式创建了一个新的Record类型的实例,该实例具有更新的 LastName
值。原始实例的值未更改。
# 结论
在C# 9.0中,Record types是一个强大的新功能,它提供了内置的功能来封装数据。在本文中,我们讨论了如何使用位置参数或标准属性语法创建Record类型,并介绍了它们提供的内置功能,例如值相等性,哈希,以及如何使用 with
表达式创建新的记录类型的实例。