C#中如何实现兼具可变与不可变版本的Record类?
解决方案
针对接口类型限制的问题:显式接口实现 + 可变属性重载
在可变Record类中,通过显式接口实现满足只读接口的契约,同时单独定义一个返回可变类型的公共属性。这样外部调用者使用可变类实例时,直接访问的是可变类型属性;当实例被转换为只读接口时,会使用显式实现的只读属性。
示例代码:
// 定义完整的只读接口契约 public interface IReadOnlyRecord { int ValueTypeProperty { get; } IReadOnlyOtherRecord RefernceTypeProperty { get; } } public interface IReadOnlyOtherRecord { int SomeData { get; } } // 可变Record类:显式实现只读接口,同时暴露可变类型属性 public record class MutableRecord : IReadOnlyRecord { // 值类型属性:直接提供可读写访问 public int ValueTypeProperty { get; set; } // 引用类型属性:暴露具体的可变Record类型 public OtherMutableRecord RefernceTypeProperty { get; set; } // 显式实现只读接口的属性,将可变类型隐式转换为只读接口 IReadOnlyOtherRecord IReadOnlyRecord.RefernceTypeProperty => RefernceTypeProperty; } public record class OtherMutableRecord : IReadOnlyOtherRecord { public int SomeData { get; set; } }
效果说明:
- 直接使用
MutableRecord实例时,RefernceTypeProperty返回OtherMutableRecord,可直接修改其属性; - 将
MutableRecord转换为IReadOnlyRecord接口时,RefernceTypeProperty返回IReadOnlyOtherRecord,仅支持读取操作; - 完全符合你接受的「调用者可强制转换为可变版本」的安全约定。
针对基类多继承的问题:接口组合 + 业务基类继承
利用C#支持多接口实现的特性,让可变Record继承业务基类的同时,实现对应的只读接口,避开多继承限制。
假设存在业务基类BusinessBase,实现示例如下:
public abstract record class BusinessBase { // 业务基类的公共逻辑 public Guid Id { get; init; } } public record class MutableRecord : BusinessBase, IReadOnlyRecord { public int ValueTypeProperty { get; set; } public OtherMutableRecord RefernceTypeProperty { get; set; } IReadOnlyOtherRecord IReadOnlyRecord.RefernceTypeProperty => RefernceTypeProperty; }
这种方式既保留了业务基类的继承关系,又通过接口实现了只读契约,完全规避多继承冲突问题。
内容的提问来源于stack exchange,提问作者sdub0800
相关产品推荐
相关产品推荐

