【问题标题】:Why can't I have a public class that inherits from an internal class?为什么我不能有一个从内部类继承的公共类?
【发布时间】:2012-01-05 05:43:51
【问题描述】:

我不明白下面显示的可访问性限制

public abstract class Base { }
internal class Common : Base { }
public class Instance : Common { }

这不会编译。

可访问性不一致:基类“Common”的可访问性低于类“Instance”

我可以使用公共抽象类 Common 完成我想要的,但为什么我不能根本不公开名称?

编辑:我要问的是为什么它是这样工作的!每个人都在回答规则是什么,而不是解释规则为什么会这样。

【问题讨论】:

  • 为什么要隐藏 Common?抽象类不能被实例化..
  • 编译不出来是什么错误?
  • @gideon,添加了错误消息。

标签: c# inheritance language-design


【解决方案1】:

类的继承者不能扩大基类的可访问范围。

public:访问不受限制 内部:仅限此程序访问

一旦受限于该程序,a, internal class 的所有继承者必须保持 internal 或假定可访问性较低(protected internalprivate)。

根据C# specification§3.5.4 可访问性约束部分

实例构造函数的参数类型必须至少为 可作为实例构造函数本身访问。

在示例中

class A {...}

public class B: A {...}

B 类导致编译时错误,因为 A 至少不是 和 B 一样易于访问。

还有:

类类型的直接基类必须至少是可访问的 作为类类型本身(§3.5.2)。例如,它是一个编译时 公共类从私有或内部类派生的错误。

如果您尝试创建一个 Common 类,该类具有您不想让外部代码访问的功能,您应该 prefer composition over inheritance。例如:

public abstract class Base
{
...
}

internal class Common : Base
{
...
}

public class Instance
{
    internal Instance(Common common)
    {
        ...
    }
...
}

【讨论】:

  • 请注意,关于实例构造函数和参数类型的部分与问题或代码 sn-p 无关,它只是该特定部分中许多项目的最后一个要点。这里的相关要点实际上是第一个,它与规范中稍后找到的第二个引用部分相匹配。
【解决方案2】:

这是代码对其他程序集的可见性的问题。通过将 Common 设置为 internal,您可以限制对其程序集的 Common 访问,而通过使 Instance 公开,您可以使任何引用程序集都可以访问 Instance。如果引用程序集无法访问类型的基类,它如何访问从该基类继承的任何成员?

【讨论】:

    【解决方案3】:

    如果Common 包含一个属性,假设Foo

    public string Foo { get; set; }
    

    Instance 类会自动公开该属性。你可以这样想:

    public void Test()
    {
        Common myInstance = new Instance();
        System.Console.WriteLine(myInstance.Foo);
    }
    

    由于Instance 需要公开Common 的所有内容,因此基类上的访问修饰符不能少公开。

    但是,您可以将属性 Foo 创建为 internal 以完成相同的工作。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-06-02
      • 1970-01-01
      • 2014-09-09
      • 1970-01-01
      • 2010-10-20
      • 1970-01-01
      • 1970-01-01
      • 2015-06-05
      相关资源
      最近更新 更多