代码之家  ›  专栏  ›  技术社区  ›  ram

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

  •  14
  • ram  · 技术社区  · 16 年前

    我今天在做一些代码回顾,偶然发现了一个由某个开发人员编写的旧代码。是这样的

    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 回复  |  直到 10 年前
        1
  •  12
  •   Hans Passant    16 年前

    最初的程序员想使派生控件可用于客户机代码。但是要防止客户机继承和干扰虚拟方法。这不是一个坏主意,通常很容易通过重写一个方法并做一些类似忘记调用基类方法的事情来破坏基类。

        2
  •  6
  •   itowlson    16 年前

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

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

        3
  •  1
  •   Paul Creasey    16 年前

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

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

        4
  •  0
  •   Vinay Pandey    16 年前

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