为什么我的公共类不能扩展内部类?

Dav*_*vid 44 c# inheritance internal

我真的不明白.

如果基类是抽象的并且仅用于为程序集中定义的公共子类提供公共功能,为什么不将它声明为内部?

我不希望抽象类对程序集外部的代码可见.我不希望外部代码知道它.

Eri*_*ert 42

更新:这个问题是我的博客2012年11月13日的主题.看看它有关这个问题的更多想法.谢谢你这个好问题!


你是对的; 它不一定是这样的.其他OO语言允许"私有继承",因此D继承自B的事实只能通过能够看到B的代码来利用.

这是原始C#设计师的设计决定.不幸的是,我现在离开了我的办公桌 - 我需要休息几天才能度过这个漫长的周末 - 所以我没有1999年的语言设计笔记.如果我在回来的时候想到它,我会浏览它们,看看是否有理由做出这个决定.

我个人认为继承应该用来代表"是一种"关系; 也就是说,继承应该表示在该语言中建模的域的语义.我尝试避免将继承用作代码共享机制的情况.正如其他人所提到的,如果你想要代表的是"这个类与其他类共享实现机制",那么最好选择组合继承.


Jus*_*ner 38

通过继承自类,您可以通过子项公开基类的功能.

由于子类具有比其父级更高的可见性,因此您将暴露将受到保护的成员.

您不能通过实现具有更高可见性的子级来违反父类的保护级别.

如果基类实际上是由公共子类使用,那么您还需要将父类公用.

另一种选择是让你的"父"保持内部,使其成为非抽象的,并使用它来组成你的子类,并使用一个接口强制类来实现这些功能:

public interface ISomething
{
    void HelloWorld();
}

internal class OldParent : ISomething
{
    public void HelloWorld(){ Console.WriteLine("Hello World!"); }
}

public class OldChild : ISomething
{
    OldParent _oldParent = new OldParent();

    public void HelloWorld() { _oldParent.HelloWorld(); }
}
Run Code Online (Sandbox Code Playgroud)

  • 谢谢.但是,为什么内部类的成员不应被视为内部成员,除非通过公共子类公开?我认为这是有道理的. (6认同)
  • 感谢您的详细回答和使用组合的建议。我是否正确地认为我的问题的答案更多的是“因为 C# 不是这样创建的”而不是“因为这样做是一件愚蠢的事情”? (2认同)
  • 我更喜欢接口方法,但我认为David特别希望将这些功能保留在"通用位置",而不必在每个派生类中重新实现相同的代码. (2认同)

Sam*_*uel 17

我认为你可以做的最接近的事情是通过使它的内部构造函数来阻止其他程序集创建抽象类,引用MSDN:

内部构造函数可防止抽象类用作与抽象类不在同一程序集中的类型的基类.

然后,您可以尝试将一个EditorBrowsableAttribute添加到类中以尝试将其隐藏在Intellisense中(尽管如此,我使用它实际上是混合的结果)或者将基类放在嵌套的命名空间中,例如MyLibrary.Internals将其与其他命名空间分开你的班级.