继承抽象类FileSystemInfo时成员重写与重载的技术咨询
核心问题拆解与解答
咱们一步步梳理你的疑问,帮你理清这里的设计逻辑和正确操作方式:
1. 关于必须重写的抽象成员(Name、Exists、Delete)
这部分你做的完全正确!FileSystemInfo作为抽象类,Name、Exists是抽象只读属性,Delete是抽象方法——抽象成员的本质就是强制子类必须提供具体实现,所以你在CFileInfo里重写这些成员完全符合框架设计要求,尤其是只读Name的重写,完美贴合基类的抽象定义,没有任何问题。
2. 针对非Overridable属性(比如CreationTime)的处理
这里要先明确一个关键区别:重载(override)和隐藏(hide)是完全不同的概念。
- 基类里像
CreationTime这类属性没有标记Overridable(C#中对应virtual关键字),意味着框架设计时就不允许子类重写它的实现逻辑。你没办法用override关键字来修改它的行为,编译器会直接报错。 - 如果你硬要在
CFileInfo里定义同名的CreationTime属性,只能用new关键字来隐藏基类成员,示例代码如下:
但这种方式有个明显的坑:当你的public new DateTime CreationTime => _fileInfo.CreationTime;CFileInfo实例被向上转型为FileSystemInfo基类引用时,调用CreationTime会触发基类的默认实现(通常是抛出异常或返回空值),而不是你子类的逻辑,很容易导致行为不一致。除非你能确保永远不会用基类引用来操作CFileInfo实例,否则不推荐这么做。
更合理的替代思路
既然你在CFileInfo的构造函数里持有了一个FileInfo实例,其实可以把所有成员的实现都委托给这个实例:
- 重写的抽象成员直接调用
_fileInfo的对应成员(比如public override string Name => _fileInfo.Name;) - 对于非Overridable的属性,如果想让外部获取正确的值,要么接受基类的默认行为(但抽象类的默认行为通常不可用),要么就用
new隐藏,但一定要清楚隐藏的局限性。
另外,也可以反思下设计思路:如果你的CFileInfo只是包装一个FileInfo对象,那组合而非继承可能是更合适的选择——让CFileInfo包含FileInfo成员,然后暴露你需要的属性和方法,这样就能彻底避免抽象类带来的这些限制。
3. 关于只读Name属性的重写
再次强调:这完全正确!FileSystemInfo里的Name就是抽象只读属性,你重写时保持只读特性,并且委托给内部FileInfo的Name,完全符合抽象类的契约要求,没有任何问题。
内容的提问来源于stack exchange,提问作者user1889116
相关产品推荐
相关产品推荐

