C# record

一、record是什么

record是为数据处理设计的类型,record 是一种拥有“值语义”的引用类型(或值类型)。

public record Person(string FirstName, string LastName);

Person的实例将分配在堆上。

二、record的核心特性

1.基于值的相等性

public record Point(int X, int Y);
var p1 = new Point(1, 2);
var p2 = new Point(1, 2);
Console.WriteLine(p1 == p2); // True

2. 简洁的不可变性
初始化后值不可变

public record Person(string FirstName, string LastName);
var p = new Person("Alice", "Smith");
// p.FirstName = "Bob"; // 错误!不可变

3.自动生成的实用成员
ToString():Person { FirstName = Alice, LastName = Smith }
Deconstruct():var (first, last) = person;
复制方法(支持 with
4.继承支持
record 支持继承,且值相等性会考虑整个继承链:
当你 new 一个子类 record 时,必须提供所有层级的所有属性值,无论这些属性是在子类还是父类中定义的。
比较时会把继承链上每一层定义的属性都拿来比较。

public record Person(string FirstName, string LastName);
public record Student(string FirstName, string LastName, int Grade) : Person(FirstName, LastName);
var personAlice = new Person("Alice", "Smith");
var studendAlice = new Student("Alice", "Smith", 6);

record父类和子类可以进行比较,结果永远是false,因为类型不同。

三、把record拿来做来做运行时持久化存在的数据

场景1:运行时持久化(内存中长期存在)
// 用户会话数据 - 运行期间一直存在

public record UserSession(
  string UserId,
  string UserName,
  DateTime LoginTime,
  HashSet<string> Permissions
);

优点
不可变性:多线程安全,不需要加锁
值相等:可以方便地作为字典键
内存开销合理

场景2:做游戏配置表数据
为什么record适合游戏配置表?
配置表的需求               record提供的特性
只读数据(运行时不应修改)          默认不可变(init)
大量配置对象需要比较          值相等性,便于查找和去重
从JSON/Excel反序列化         原生支持 System.Text.Json
多人配置不会相互干扰               不可变保证线程安全
运行时查询效率             可作为字典键,支持哈希
实际示例:

// 物品配置表
public record ItemConfig(
    int Id,                    // 唯一ID
    string Name,              // 名称
    ItemType Type,            // 类型枚举
    int Price,                // 价格
    string IconPath,          // 图标路径
    string Description        // 描述
);

public class GameConfigManager
{
    // 运行时持久化的配置数据
    private readonly Dictionary<int, ItemConfig> _items = new();
    // 加载配置(从JSON文件)
    public void LoadConfigs(string configPath)
    {
        var json = File.ReadAllText(Path.Combine(configPath, "items.json"));
        var items = JsonSerializer.Deserialize<List<ItemConfig>>(json);
        foreach (var item in items)
        {
            _items[item.Id] = item;  // 存储 record 实例
        }
    }
    // 运行时查询配置
    public ItemConfig GetItem(int id)
    {
        if (_items.TryGetValue(id, out var config))
            return config;
        
        throw new KeyNotFoundException($"Item config {id} not found");
    }
    // 运行时查找(利用值相等性)
    public ItemConfig? FindItemByName(string name)
    {
        return _items.Values.FirstOrDefault(item => item.Name == name);
    }
}

// 使用示例
public class GameLogic
{
    private readonly GameConfigManager _config = new();
    
    void Start()
    {
        _config.LoadConfigs("Configs/");
        var sword = _config.GetItem(1001);
        Console.WriteLine($"获得武器:{sword.Name},价格:{sword.Price}");
    }
}
posted @ 2026-05-18 16:26  apssic  阅读(6)  评论(0)    收藏  举报