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

如何让抽象类中的属性仅能在子类构造函数中赋值?

问题:抽象类中仅get属性如何限制子类仅在构造函数中赋值

原本在具体类中有一个仅含get访问器的属性,按照定义它只能在该类的构造函数中赋值。现在需要将这个属性移到无构造函数的抽象类中,子类继承该抽象类后,如何保证抽象类中的这个属性仅能在子类的构造函数中被赋值?

以下方案已被排除:

  • 为属性添加protected set修饰符:会让子类获得超出需求的权限(子类的任意方法都能修改属性,不止构造函数)
  • 使用init访问器:不符合仅在构造函数中赋值的要求(init允许在对象初始化器中赋值,范围更广)
  • 直接依赖readonly字段的便捷写法:当前使用C# 7.3版本,不支持相关特性

原始代码示例

最初的具体类

public class FooOriginal
{
   public int IntHere { get; }
}

重构后的抽象类

public abstract class FooAbstract
{
   public int IntHere { get; }
}

编译失败的子类

public class FooChild : FooAbstract
{
   public FooChild()
   {
       // 无法编译:IntHere是仅get属性,子类无法直接赋值
       IntHere = 3;
   }
}

可行解决方案(适配C# 7.3)

通过将抽象类的属性拆分为protected readonly底层字段+仅get的公开属性,既满足子类仅能在构造函数中赋值,又严格限制权限:

修改后的抽象类

public abstract class FooAbstract
{
    // protected readonly字段:子类仅能在构造函数中赋值
    protected readonly int _intHere;
    // 公开的仅get属性,对外暴露字段值
    public int IntHere => _intHere;
}

正确赋值的子类

public class FooChild : FooAbstract
{
    public FooChild()
    {
        // 仅能在构造函数中给readonly字段赋值,符合要求
        _intHere = 3;
    }
}

方案说明

  1. protected readonly字段的特性:子类可以在自身构造函数中赋值,但无法在其他方法中修改,完美匹配“仅构造函数赋值”的需求
  2. 公开的IntHere属性仅提供get访问器,外部代码无法修改属性值
  3. 完全适配C# 7.3版本,无需依赖更高版本的语法特性
  4. 避免了protected set带来的过度权限问题

内容的提问来源于stack exchange,提问作者J. Mini

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 23:02:41