对于那些在大型项目和 API/框架设计方面有经验的人来说,这是一个问题。
我正在开发一个将来会被许多其他项目使用的框架,所以我想让它变得漂亮和可扩展,但同时它需要简单易懂。
我知道很多人抱怨 .NET 框架包含太多的密封类和私有成员。我是否应该避免这种批评并用大量受保护的虚拟成员打开我的所有课程?
尽可能多地使我的方法和属性受保护是一个好主意吗?在什么情况下你会避免受保护的虚拟并让成员私有。
你的类包括数据成员;对那些功能永远不应该改变的数据成员执行基本内部操作的方法应该始终是私有的。因此,对数据成员进行基本操作(例如初始化和分配)的方法应该是私有的。否则,您将面临“二阶”派生类启用不完整行为集的风险;一阶导数成员可能会重新定义类的行为。
综上所述,我认为您应该非常小心地将方法定义为“受保护的虚拟”。在将方法定义为“受保护的虚拟”时,我会非常谨慎,因为这样做不仅声明了覆盖功能的可能性,而且在某些方面定义了对覆盖功能的期望。在我看来,这听起来像是一组定义不足的行为。我宁愿有一套明确定义的行为来覆盖。如果您想拥有大量可覆盖的行为,我宁愿研究面向方面的编程,它以非常结构化的方式允许这种事情。
当您使用单词 virtual 标记方法时,您允许用户更改该逻辑的执行方式。出于许多目的,这正是您想要的。我相信你已经知道了。
但是,应该为这种扩展设计类型。你必须主动选择方法,让用户改变行为是有意义的。如果你只是在所有地方都贴上 virtual ,你可能会破坏类型的完整性,它并不能真正帮助用户理解类型,并且你可能会引入许多错误,包括与安全相关的问题。
我更喜欢保守的方法。sealed
除非我特别想启用继承,否则我会标记我的所有类,并且在那些(少数)情况下,我只会将所需的方法设为虚拟。
sealed
如果将来需要更改类以允许继承,则很容易删除标记。但是,如果您想更改一个已经被用作其他类型的基类的类,则在更改基类时可能会破坏子类。
我的观点是:
events
,则首选protected
方法。protected
使用方法,如果不可能,那么你必须使用它;-)。选择是一个深思熟虑的设计决定protected
。private
您是在声明您的类明确支持使用该功能,以及随之而来的所有开销(设计和实现工作)。我只会protected
在我知道有必要的情况下使用,主要是因为我自己在做。(您还会发现 BCL 开发人员的评论与我所说的内容相同。)
virtual
/non-virtual
性能差异与任何强大到足以运行 .NET Framework 的机器无关。
不,你不能有“太多”。然而,我们应该不惜一切代价使每个受保护而不是私有或避免“密封”的想法是愚蠢的。我会将“辅助方法”和内部数据结构保密。