繁体   English   中英

C#继承私有类并且不访问公共成员

[英]C# inherit private class and non-access of public member

私有类的子类的用户为什么不能访问私有类的公共成员数据? 以下内容对我来说似乎很违反直觉,因为它不会被编译:

public class OuterClassBase {
    private class PrivateInnerClass {
        public void DoSomething () {}
    }

    protected class ProtectedInnerClass : PrivateInnerClass {}
}


public class OuterClassDerived : OuterClassBase {
    public OuterClassDerived () {
        ProtectedInnerClass o = new ProtectedInnerClass();
        o.DoSomething(); // inaccessible due to its pretection level
    }
}

PrivateInnerClass公开/受保护可允许代码进行编译...

根据C#4规范的第3.5节:

成员声明允许控制成员访问。 成员的可访问性由成员的声明的可访问性(第3.5.1节)和直接包含的类型(如果有)的可访问性相结合来确定。
...
当进行访问的文本位置包含在该成员的可访问性域(第3.5.2节)中时,允许访问该成员。

然后在3.5.2节(可访问性域)中:

程序P中以类型T声明的嵌套成员M的可访问域定义如下(请注意,M本身可能是类型):

  • 如果声明的M的可访问性是公共的,则M的可访问域是T的可访问域。
  • ...
  • 如果声明的M的可访问性是私有的,则M的可访问域是T的程序文本。

就是这种情况。 所以的访问域DoSomething是可访问域PrivateInnerClass第一子弹......但是的访问域PrivateInnerClass是程序文本OuterClassBase被最后一颗子弹。

因此, OuterClassDerived的调用不在 DoSomething的可访问性域中,因此无法调用。

我真的很惊讶您首先可以从PrivateInnerClass派生ProtectedInnerClass ...

编辑:事实证明,您无法...甚至完全删除了OuterClassDerived类,也会收到此错误:

Test.cs(10,21): error CS0060: Inconsistent accessibility: base class
        'OuterClassBase.PrivateInnerClass' is less accessible than class
        'OuterClassBase.ProtectedInnerClass'

这违反了规范的10.1.4.1节:

类类型的直接基类必须至少具有与类类型本身一样的可访问性(第3.5.2节)。 例如,公共类从私有类或内部类派生是编译时错误。

在这里,您尝试从私有类派生受保护的类-受保护的类比私有类更易于访问,因此会出现错误。

PrivateInnerClass对OuterClassBase是私有的-除OuterClassBase外,没有人可以使用它(这是private的意思)。

对其进行子类化不会更改规则,但它仍然是私有的-如果子类化将打破私有性约束并允许OuterBaseClass之外的其他人访问PrivateInnerClass的成员,则此行为是非法的且无法编译。

换句话说,如果某事物被声明为私有而不是私有,则任何允许您通过私有声明的技巧都不应编译(反射除外)。

受保护的类不能从私有类继承,其原因与公共类不能从内部类继承的原因相同:类不能比其基类更易访问。

但是,为什么要尝试这样做? 您可以防止其他类直接从PrivateInnerClass继承,但前提是它们在不同的程序集中。 您也可以这样做。 该框架对内部/公共类做了很多工作:

public class OuterClassBase
{
    private class PrivateInnerClass : ProtectedInnerClass
    {
    }

    protected abstract class ProtectedInnerClass
    {
        public void DoSomething() { }
    }

    protected ProtectedInnerClass ProtectedInnerClassFactoryMethod()
    {
        return new PrivateInnerClass();
    }
}

public class OuterClassDerived : OuterClassBase
{
    public OuterClassDerived()
    {
        ProtectedInnerClass o = ProtectedInnerClassFactoryMethod();
        o.DoSomething();
    }
} 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM