随着 C# 9 的发布,Microsoft 引入了记录,这是一种新的引用类型,可显著简化不可变数据对象的创建。记录特别适用于不可变性和值相等性至关重要的方案,例如数据传输对象 (DTO)、配置对象等。
在这篇文章中,我们将探讨 C# 9 中记录的详细信息、如何有效地使用它们,以及它们可以大大增强代码的一些高级方案。
C# 9 中的记录提供了一种简洁的方法来定义具有内置值相等性的不可变数据对象。与传统类不同,记录被设计为默认不可变,这意味着它们的状态在创建后无法修改。
基本记录声明
下面是 C# 9 中记录的简单示例:
public record Person(string FirstName, string LastName);
在此示例中,是具有两个属性的记录:和 。编译器会自动为此记录生成多个成员,包括:PersonFirstNameLastName
记录的关键特征之一是不可变性。创建记录后,无法修改其属性。但是,您可以使用 with-expressions 创建更改某些属性的新记录:
var person = new Person("John", "Doe");
var updatedPerson = person with { LastName = "Smith" };
Console.WriteLine(person); // Output: Person { FirstName = John, LastName = Doe }
Console.WriteLine(updatedPerson); // Output: Person { FirstName = John, LastName = Smith }
该关键字创建记录的新实例,复制现有值并应用指定的更改。with
记录提供内置值相等,这意味着具有相同数据的两条记录被视为相等:
var person1 = new Person("John", "Doe");
var person2 = new Person("John", "Doe");
Console.WriteLine(person1 == person2); // Output: True
Console.WriteLine(person1.Equals(person2)); // Output: True
此行为与类形成鲜明对比,在类中,默认情况下,相等性基于对象引用。
位置记录
位置记录允许您使用位置参数定义记录,使代码更加简洁:
public record Point(int X, int Y);
var point = new Point(1, 2);
var (x, y) = point; // Deconstruction
Console.WriteLine($"X: {x}, Y: {y}"); // Output: X: 1, Y: 2
自定义记录
虽然记录提供了许多内置功能,但您可以通过添加其他方法或覆盖现有方法来自定义它们:
public record Person(string FirstName, string LastName)
{
public string FullName => $"{FirstName} {LastName}";
public override string ToString() => $"Person: {FullName}";
}
var person = new Person("John", "Doe");
Console.WriteLine(person); // Output: Person: John Doe
记录和继承
记录支持继承,允许您创建不可变类型的层次结构:
public record Person(string FirstName, string LastName);
public record Employee(string FirstName, string LastName, string Position) : Person(FirstName, LastName);
var employee = new Employee("John", "Doe", "Developer");
Console.WriteLine(employee); // Output: Employee { FirstName = John, LastName = Doe, Position = Developer }
非位置记录
您还可以定义非位置记录,从而更好地控制属性初始化:
public record Car
{
public string Make { get; init; }
public string Model { get; init; }
public Car(string make, string model)
{
Make = make;
Model = model;
}
}
var car = new Car("Toyota", "Corolla");
Console.WriteLine(car); // Output: Car { Make = Toyota, Model = Corolla }
记录中的可变性
虽然默认情况下记录是不可变的,但如有必要,您可以定义可变记录。但是,通常不鼓励这样做,因为它违背了记录的主要设计原则:
public record MutablePerson
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
记录在不可变性和值相等很重要的方案中特别有用。以下是一些实际应用:
数据传输对象 (DTO)
记录是 DTO 的理想选择,DTO 通常需要不可变性和值相等:
public record CustomerDto(int Id, string Name, string Email);
配置对象
记录提供了一种方便的方法来定义配置对象,这些对象在初始化后不应更改:
public record AppConfig(string ConnectionString, int MaxRetries);
活动溯源
在事件源系统中,记录可用于表示不可变事件:
public record OrderPlaced(Guid OrderId, DateTime PlacedAt, decimal Amount);
C# 9 中的记录引入了一种强大而简洁的方法来定义具有内置值相等性的不可变数据对象。通过利用记录,您可以创建更可靠和可维护的代码,尤其是在不可变性和值平等至关重要的情况下。
无论您使用的是 DTO、配置对象还是事件源系统,记录都提供了一种在 C# 中定义数据结构的现代高效方法。采用此功能可增强您的 C# 编程技能并构建更可靠的应用程序。