如何让抽象基类的抽象属性在继承类中强制实现并可通过基类访问
问题描述
定义了抽象基类BaseObject:
public abstract class BaseObject { internal abstract string DatabaseTableName { get; } internal abstract string ObjectType { get; } // 其他无关类成员 }
该基类有两个仅Id类型不同的抽象子类:
public abstract class BaseObject32 : BaseObject { public int Id { get; private set; } // 其他无关类成员 } public abstract class BaseObject64 : BaseObject { public long Id { get; private set; } // 其他无关类成员 }
需求是:所有继承BaseObject32或BaseObject64的类必须实现DatabaseTableName和ObjectType这两个属性,且这些属性能通过BaseObject类的实例访问。期望的最终派生类实现示例如下:
public class Cat : BaseObject32 { // 期望的简化实现形式 DatabaseTableName => "animals.cat"; ObjectType => "Cat"; }
并能执行如下操作:
BaseObject c = new Cat(); string x = c.DatabaseTableName;
但实际尝试时,即使添加new或override关键字,编译器仍提示需要实现继承的类成员,目前期望每个派生类的实现代码大致如下:
private const string _ObjectType = "Cat"; private const string _DatabaseTableName = "animals.cat"; internal override string ObjectType => _ObjectType; internal override string DatabaseTableName => _DatabaseTableName;
解决方案
核心问题在于BaseObject32和BaseObject64作为抽象类,继承了BaseObject的抽象成员,但未将这些成员继续标记为抽象,导致编译器要求中间类实现它们。只需在中间类中把这两个属性声明为abstract override,即可将实现责任传递给最终的派生类,同时保留多态性。
1. 修改中间抽象类
更新BaseObject32和BaseObject64,显式将两个抽象属性传递下去:
public abstract class BaseObject32 : BaseObject { public int Id { get; private set; } // 用abstract override强制派生类实现 internal abstract override string DatabaseTableName { get; } internal abstract override string ObjectType { get; } // 其他无关类成员 } public abstract class BaseObject64 : BaseObject { public long Id { get; private set; } internal abstract override string DatabaseTableName { get; } internal abstract override string ObjectType { get; } // 其他无关类成员 }
2. 实现最终派生类
以Cat类为例,正确实现两个属性(注意修正拼写:基类属性是DatabaseTableName,而非DataBaseTableName):
public class Cat : BaseObject32 { private const string _ObjectType = "Cat"; private const string _DatabaseTableName = "animals.cat"; internal override string ObjectType => _ObjectType; internal override string DatabaseTableName => _DatabaseTableName; }
3. 验证访问
此时即可正常通过BaseObject实例访问属性:
BaseObject c = new Cat(); string x = c.DatabaseTableName; // 输出 "animals.cat"
内容的提问来源于stack exchange,提问作者Hambone
相关产品推荐
相关产品推荐

