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

时间:2010-02-20 20:23:53

标签: c# inheritance abstract-class override access-modifiers

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

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()

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

4 个答案:

答案 0 :(得分:12)

原始程序员想要为客户端代码提供派生控件。但是要防止客户端继承和搞乱虚拟方法。这不是一个坏主意,通常可以通过重写方法并执行类似忘记调用基类方法的操作来打破基类。

答案 1 :(得分:6)

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

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

答案 2 :(得分:1)

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

我认为这种方法可以防止外部继承,同时保持可见性。

答案 3 :(得分:0)

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

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