如何在C# 11中为基类的init属性使用通用初始化器?
C# 11 中派生类复用基类 required 属性初始化的方案
问题场景
给定C# 11中的基类与派生类:
class BaseClass { public required string BaseProperty { get; init; } } class ChildClass : BaseClass { public required string ChildProperty { get; init; } }
标准初始化方式需要同时显式设置基类和派生类的required属性:
var a = new ChildClass { BaseProperty = "abc", ChildProperty = "def" };
当基类属性较多或派生类数量庞大时,这种重复初始化基类属性的操作会非常繁琐。我们需要一种集中处理基类属性初始化的方式,让派生类仅需关注自身新增属性的初始化。
可行解决方案
方案1:基类定义构造函数,派生类复用
在基类中定义包含所有required属性的构造函数,派生类通过: base(...)调用该构造函数,避免重复编写基类属性的初始化逻辑。
class BaseClass { public required string BaseProperty { get; init; } // 封装基类required属性的初始化逻辑 protected BaseClass(string baseProperty) { BaseProperty = baseProperty; } } class ChildClass : BaseClass { public required string ChildProperty { get; init; } // 派生类构造函数,调用基类构造函数初始化基类属性 public ChildClass(string baseProperty, string childProperty) : base(baseProperty) { ChildProperty = childProperty; } // 可选:保留对象初始化语法的重载 public ChildClass(string baseProperty) : base(baseProperty) { } }
使用示例:
// 直接通过构造函数完成全部初始化 var a = new ChildClass("abc", "def"); // 结合对象初始化器,仅设置派生类属性 var b = new ChildClass("abc") { ChildProperty = "def" };
方案2:工厂方法封装基类初始化逻辑
创建通用工厂方法封装基类属性的初始化逻辑,派生类可以直接复用该方法,仅补充自身属性的设置。
static class BaseClassFactory { // 封装基类默认初始化逻辑,支持所有BaseClass的派生类 public static T CreateBaseInitialized<T>() where T : BaseClass, new() { return new T { BaseProperty = "abc" }; } // 支持动态参数的重载版本 public static T CreateBaseInitialized<T>(string baseProperty) where T : BaseClass, new() { return new T { BaseProperty = baseProperty }; } }
使用示例:
void Main() { // 使用默认参数初始化基类,再设置派生类属性 var a = BaseClassFactory.CreateBaseInitialized<ChildClass>() { ChildProperty = "def" }; // 传入自定义基类属性值 var b = BaseClassFactory.CreateBaseInitialized<ChildClass>("customValue") { ChildProperty = "def" }; }
方案3:利用 SetsRequiredMembers 属性简化
通过C# 11的[SetsRequiredMembers]属性标记基类构造函数,构造函数内部完成基类required属性的初始化,派生类继承后无需重复设置。
class BaseClass { public required string BaseProperty { get; init; } [SetsRequiredMembers] protected BaseClass() { // 集中初始化基类required属性 BaseProperty = "abc"; } } class ChildClass : BaseClass { public required string ChildProperty { get; init; } }
使用示例:
// 仅需设置派生类的required属性即可 var a = new ChildClass { ChildProperty = "def" };
说明
C# 目前并不支持你设想的new ChildClass : BaseInitializer()这类语法,但通过上述方案,完全可以实现基类属性的集中式初始化,让required和init关键字在继承场景下依然能高效使用。
内容的提问来源于stack exchange,提问作者Mike
相关产品推荐
相关产品推荐

