内部抽象方法。 为什么有人会拥有它们?

我今天正在进行一些代码审查,并遇到了一些开发人员编写的旧代码。 它就是这样的

public abstract class BaseControl { internal abstract void DoSomething(); } 

如果在同一个程序集中有一个派生类,它就可以工作

 public class DerivedControl : BaseControl { internal override void DoSomething() { } } 

但是在不同的程序集中派生基类会产生编译时错误

 DerivedControl does not implement inherited abstract member 'BaseControl.DoSomething() 

这让我思考。 为什么有人会将方法声明为内部抽象?

原始程序员希望为客户端代码提供派生控件。 但是要防止客户端inheritance和搞乱虚拟方法。 这不是一个坏主意,通过覆盖方法并执行类似忘记调用基类方法的操作来打破基类通常很容易。

一个明显的例子是方法接收或返回内部类型。 例如,WPF转换类的核心方法处理一些内部互操作类型,WPF不会将其作为其公共API的一部分公开。 由于签名包含内部类型,因此该方法不能公开或受保护。 但显然,各种Transform类以多态方式工作是合适的(必要的!)。 因此,Transform / GeneralTransform中的基本方法必须是内部的。

另一个但相关的原因是防止外部推导。 毕竟,WPF架构师可以在受保护的抽象方法中公开内部互操作类型的“安全”版本,以便用户可以创建自己的Transform类。 他们没有,因为他们不想要处理人们使用这种能力的方式,例如创造非仿射变换。 允许外部派生会使WPF中其他类的工作变得非常复杂,因此架构师决定通过在内部创建抽象方法来仅允许“已批准”的派生类。

我最初的反应是没有充分的理由,如果你想要阻止外部inheritance,那么你应该将类标记为内部。 但这意味着该类对其他程序集完全隐藏。

我想这种方法可以防止外部inheritance,同时保持可见性。

通过将方法定义为内部抽象,您需要确保只有同一程序集中的类才能为您的方法实现其实现。

现在,如果你分发一个dll,这将避免客户端inheritance和消除实现。