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

我真的不明白。

如果基类是抽象的,只是用来为程序集中定义的公共子类提供通用的function,为什么不应该把它声明为内部的呢?

我不希望抽象类在程序集外部可见。 我不希望外部代码知道它。

通过inheritance一个类,你通过你的孩子公开基类的function。

由于儿童class级的可见度高于父母,因此您将暴露会被保护的成员。

通过实施具有较高可见度的子级,您不能违反父级的保护级别。

如果基类实际上是为公共子类使用的,那么你也需要公开父类。

另一个select是保持你的“父”的内部,使其非抽象,并用它来组成你的子类,并使用接口强制类来实现function:

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

更新:这个问题是我的博客在2012年11月13日的主题 。 看看它在这个问题上的更多想法。 感谢您的好问题!


你是对的; 它不一定是那样的。 其他OO语言允许“私有inheritance”,由此D从Binheritance的事实只能被有能力看到B的代码利用。

这是原始C#devise人员的devise决定。 不幸的是,我现在已经离开了我的办公桌 – 我在长周末rest了几天 – 所以我没有1999年的语言devise笔记在我面前。 如果我回想起来,我会浏览他们,看看是否有这个决定的理由。

我个人的看法是,应该用inheritance来代表“是一种”关系; 也就是说,inheritance应该代表在语言中build模的域的语义 。 我尽量避免使用inheritance作为代码共享机制的情况 。 正如其他人所提到的,如果你想expression的是“这个类与其他类共享实现机制”,那么最好是把组合inheritance。

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

内部构造函数可以防止抽象类被用作与抽象类不在同一个程序集中的types的基类。

然后,你可以尝试添加一个EditorBrowsableAttribute到类来试图隐藏它从Intellisense(虽然,我有混合结果使用它是诚实的),或将基类embedded命名空间,如MyLibrary.Internals分离它从你的其他课程。

我认为你在这里混合的问题,实际上(和之前的Java)C#是责备。

inheritance应该作为一个分类机制,而它通常用于代码重用。

对于代码重用,总是知道组合胜过inheritance。 C#的问题是,它给了我们这样一个简单的方法来inheritance:

 class MyClass : MyReusedClass { } 

但为了撰写,我们需要自己去做:

 class MyClass { MyReusedClass _reused; // need to expose all the methods from MyReusedClass and delegate to _reused } 

缺less的是像特质(pdf)这样的构造,这将使得构图与inheritance一样具有相同的可用性级别。

有关于C#(pdf)特性的研究,它看起来像这样:

 class MyClass { uses { MyTrait; } } 

尽pipe我希望看到另一个模型 (Perl 6angular色的模型 )。

更新:

作为一个侧面说明,Oxygene语言具有一个function ,可以让您将接口的所有成员委托给实现该接口的成员属性:

 type MyClass = class(IReusable) private property Reused : IReusable := new MyReusedClass(); readonly; implements public IReusable; end; 

在这里, IReusable所有接口成员将通过MyClass公开,他们将全部委托给Reused属性。 但是,这种方法有一些问题 。

其他更新:

我已经开始在C#中实现这个自动组合的概念:看看NRoles 。

我认为这会违反里斯科换人原则 。

在这样的情况下,我已经使用了内部类,而不是inheritance。 有没有关于你的devise,禁止在你的内部类中包含所有这些function,然后让你的公共类包含这个内部类的实例?