14

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

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

4 回答 4

12

最初的程序员希望使派生控件可用于客户端代码。但是要防止客户端继承和弄乱虚方法。这不是一个坏主意,通过重写方法并执行诸如忘记调用基类方法之类的操作通常很容易破坏基类。

于 2010-02-20T21:21:25.920 回答
6

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

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

于 2010-02-20T20:36:34.770 回答
1

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

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

于 2010-02-20T20:35:32.120 回答
0

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

现在,如果您分发它的 dll,这将避免客户端继承和中断实现。

于 2010-02-22T12:24:30.450 回答