You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用自定义record复制构造函数时字段未初始化的原因?

问题:C# Record自定义复制构造函数后字段初始化失效

定义如下Record类型:

record Foo {
    string _bar = "initialized";
    public string Bar => _bar;
}

运行测试代码:

var foo = new Foo();
Console.WriteLine(foo?.Bar ?? "null");
var foo2 = foo with { };
Console.WriteLine(foo2?.Bar ?? "null");

输出结果:

initialized
initialized

但添加自定义复制构造函数后:

protected Foo(Foo other) {
    Console.WriteLine("---my cloning method---");
}

重新运行测试代码,输出变为:

initialized
---my cloning method---
null

疑问:自定义复制构造函数未执行字段初始化代码,按常理编译器会将字段初始化代码注入构造函数,为何此处未生效?


解答

这是C# Record的设计规则导致的:

  • 未自定义复制构造函数时,编译器会自动生成默认复制构造函数,这个自动生成的构造函数会同时处理两件事:执行字段的初始化代码(比如_bar = "initialized"),以及从原实例复制所有字段的值。
  • 一旦手动定义了复制构造函数,编译器就会停止生成默认的复制逻辑,完全交由开发者实现构造函数内容。此时字段初始化代码不会自动注入到自定义复制构造函数中,也不会自动复制原实例的字段值。

你的自定义复制构造函数里没有对_bar做任何赋值操作,所以它会保持字符串类型的默认值null,最终输出null。

如果需要保留原实例的字段状态,只需在自定义复制构造函数中手动复制原实例的字段:

protected Foo(Foo other) {
    Console.WriteLine("---my cloning method---");
    _bar = other._bar; // 手动复制原实例的_bar字段值
}

这样修改后,运行测试代码就会重新输出两次initialized,同时触发自定义构造函数的日志。


内容的提问来源于stack exchange,提问作者Ivan Petrov

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 21:17:33