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

如何在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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 03:05:40