为何调用record struct无参构造时实际执行default(MyRecord)?
C# Record Struct 无参构造调用异常问题及解决方案
问题场景
定义如下record struct:
public record struct MyRecord(string Whatever = "anything"){ public DateTime Start {get; init;} = DateTime.UtcNow; public DateTime? End {get; init;} }
调用new MyRecord()时,编译器实际生成的代码是default(MyRecord),而非我们定义的主构造函数;只有当给主构造函数的任意参数传值时,才会正确调用new MyRecord(whatever)。这会导致Start属性始终处于零初始化状态——对应0 ticks的时间(即0001年1月1日 00:00:00)。
问题原因
这是C#编译器针对值类型(包括record struct)的重载解析规则导致的:对于值类型,new T()形式的无参调用会被优先解析为返回default(T)(值类型的零初始化状态),而非调用带有全部默认参数的构造函数。编译器默认认为零初始化的性能开销更低,因此优先选择这条路径,忽略了我们期望的构造函数逻辑。
.NET 9+ 解决方案
给主构造函数添加OverloadResolutionPriority特性,提升其重载解析优先级:
[method:System.Runtime.CompilerServices.OverloadResolutionPriority(1)] public record struct MyRecord(string Whatever = "anything"){ public DateTime Start {get; init;} = DateTime.UtcNow; public DateTime? End {get; init;} }
添加该特性后,编译器会优先选择我们定义的主构造函数,new MyRecord()将正确执行构造函数中的初始化逻辑,Start属性会被设置为当前UTC时间。
内容的提问来源于stack exchange,提问作者Cine
相关产品推荐
相关产品推荐

