掌握 C# 中的记录:深入了解 C# 9 的不可变性功能

31a31679ca793a097789ccfebd544271.jpeg

介绍

随着 C# 9 的发布,Microsoft 引入了记录,这是一种新的引用类型,可显著简化不可变数据对象的创建。记录特别适用于不可变性和值相等性至关重要的方案,例如数据传输对象 (DTO)、配置对象等。

在这篇文章中,我们将探讨 C# 9 中记录的详细信息、如何有效地使用它们,以及它们可以大大增强代码的一些高级方案。

什么是Records?

C# 9 中的记录提供了一种简洁的方法来定义具有内置值相等性的不可变数据对象。与传统类不同,记录被设计为默认不可变,这意味着它们的状态在创建后无法修改。

基本记录声明

下面是 C# 9 中记录的简单示例:

public record Person(string FirstName, string LastName);

在此示例中,是具有两个属性的记录:和 。编译器会自动为此记录生成多个成员,包括:PersonFirstNameLastName

  • 接受 和 的构造函数。FirstNameLastName

  • 和 的只读属性。FirstNameLastName

  • 位置模式匹配的解构方法。

  • 基于值的相等方法 (, )。EqualsGetHashCode

Immutability and With-Expressions

记录的关键特征之一是不可变性。创建记录后,无法修改其属性。但是,您可以使用 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

Value Equality

记录提供内置值相等,这意味着具有相同数据的两条记录被视为相等:

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

此行为与类形成鲜明对比,在类中,默认情况下,相等性基于对象引用。

Advanced Scenarios

位置记录

位置记录允许您使用位置参数定义记录,使代码更加简洁:

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# 编程技能并构建更可靠的应用程序。

如果你喜欢我的文章,请给我一个赞!谢谢

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值