简介:
Record(记录类型)是 C# 9.0 (.NET 5) 引入的一个非常强大的特性。它的核心目的是简化不可变数据模型的创建,并自带值相等性语义。
示例:
public record ConfigSettings
{
public string IpAddress { get; init; }
public int Port { get; init; }
}
或者极简写法
public record ConfigSettings(string IpAddress, int Port);
特性:
- 值相等性:两个 record 对象,只要里面的属性值完全一样,它们就被视为相等。
// 1. 普通的 class
public class ConfigClass
{
public string IpAddress { get; set; }
public int Port { get; set; }
}
// 2. record(用你喜欢的传统属性写法)
public record ConfigRecord
{
public string IpAddress { get; init; }
public int Port { get; init; }
}
class Program
{
static void Main()
{
// ============ 测试 class ============
var class1 = new ConfigClass { IpAddress = "192.168.1.1", Port = 8080 };
var class2 = new ConfigClass { IpAddress = "192.168.1.1", Port = 8080 };
Console.WriteLine("=== class 比较 ===");
Console.WriteLine($"class1 == class2 : {class1 == class2}"); // 输出 False!
Console.WriteLine($"class1.Equals(class2) : {class1.Equals(class2)}"); // 输出 False!
// ============ 测试 record ============
var record1 = new ConfigRecord { IpAddress = "192.168.1.1", Port = 8080 };
var record2 = new ConfigRecord { IpAddress = "192.168.1.1", Port = 8080 };
Console.WriteLine("\n=== record 比较 ===");
Console.WriteLine($"record1 == record2 : {record1 == record2}"); // 输出 True!
Console.WriteLine($"record1.Equals(record2) : {record1.Equals(record2)}"); // 输出 True!
}
}
-
不可变性:record 默认的属性是 { get; init; }。也就是说,你只能在创建对象时赋值(或使用 with 表达式),一旦创建,就不能再修改。
注意: 如果你在 record 里手动写了 { get; set; },它就变成了可变对象,值相等性会失效(因为它底层变成了引用类型比较)。所以用 record 尽量保持不可变。
var config = new ConfigSettings("192.168.1.1", 8080);
// config.Port = 9090; // ❌ 编译报错!不可修改
- with 表达式:既然对象不可变,那我想改其中一个属性怎么办?用 with 表达式克隆一个新的
var config1 = new ConfigSettings("192.168.1.1", 8080);
// 克隆一个 config2,只修改 Port 属性
var config2 = config1 with { Port = 9090 };
// config1 还是原来的 8080,config2 是 9090,互不影响
- 自动生成 ToString():打印 record 对象,会自动输出所有属性的值,极其方便调试
Console.WriteLine(config1);
// 输出:ConfigSettings { IpAddress = 192.168.1.1, Port = 8080 }