C#怎么使用record类型 C# 9.0新特性record使用方法

record 是 C# 9.0 引入的轻量级引用类型,专为不可变数据建模设计,自动提供值语义、ToString()、位置解构和 with 表达式;支持位置声明与类体形式,with 实现浅拷贝式副本修改,但需注意其引用本质与浅拷贝限制。

record 是 C# 9.0 引入的轻量级引用类型,专为不可变数据建模设计,自动提供值语义(如 EqualsGetHashCode)、ToString()、位置解构和 with 表达式等能力,省去大量样板代码。

声明 record 的基本语法

最简形式用 record 关键字加类名和括号内属性列表(位置 record):

public record Person(string Name, int Age);

编译器自动生成:私有只读字段、公有 init-only 属性、构造函数、相等比较逻辑、格式化字符串输出等。

你也可以写成类体形式(非位置 record),手动定

义属性,但需显式标记 init 以保持不可变性:

public record Student
{
    public string Id { get; init; }
    public string Name { get; init; }
    public int Grade { get; init; }
}

使用 with 表达式创建副本并修改部分字段

with 是 record 的核心特性之一,用于基于现有实例生成新实例(浅拷贝),只改指定字段,其余保持不变:

  • ✅ 正确用法:var adult = person with { Age = 18 };
  • ✅ 支持嵌套修改:var updated = student with { Name = "Alice", Grade = 95 };
  • ❌ 不能用于普通 class:只有 record 或继承自 record 的类型支持 with

自定义 record 行为(可选)

record 默认是不可变且按值比较的,但你可以按需扩展:

  • 重写 ToString()public override string ToString() => $"[{Name}, {Age}]";
  • 添加方法或只读属性:public bool IsAdult => Age >= 18;
  • 支持解构:public void Deconstruct(out string name, out int age) => (name, age) = (Name, Age);,之后可用 var (n, a) = person;
  • 继承 record:public record Employee(string Name, int Age, string Department) : Person(Name, Age);

注意事项和常见误区

record 不是万能替代 class 的方案:

  • 它默认是引用类型,不是值类型(别和 struct 混淆);
  • 字段仍是引用,with 只做浅拷贝——若含可变引用对象(如 List),内部内容仍共享;
  • 不支持无参构造函数(位置 record 必须传参),如需默认实例可加静态只读字段:public static readonly Person Empty = new("", 0);
  • 在需要频繁修改状态的场景(如 UI ViewModel、DTO 绑定),传统 class + 属性通知可能更合适。

基本上就这些。record 适合表达“数据是什么”,而不是“数据能做什么”。用对了,代码更简洁、语义更清晰。