嵌套派生类可以访问私有成员变量,但不能访问嵌套或派生类。为什么?

时间:2013-11-30 18:58:37

标签: c# class inheritance

这是受到我根据该计划喜欢编写单元测试的客户所做的一些工作的启发:

每个班级的一个测试班;每个公共方法一个嵌套类。

所以测试类看起来像这样:

public class TestWidget
{
    private Mock<IDoSomething> _mockSomethingDoer = new Mock<IDoSomething>();
    private Widget _widget = new Widget(_mockSomethingDoer);

    public class OpenCan : TestWidget
    {
        [Fact]
        public void GeneratesFroth()
        {
            // ARRANGE
            _mockSomethingDoer.SetUp(...);

            // ACT
            _widget.OpenCan();

            // ASSERT
            _widget.Should().Have().Generated().Froth();
        }

        [Fact]
        public void DoesNotSpillEverywhere()
        {
            // ARRANGE
            _mockSomethingDoer.SetUp(...);

            // ACT
            _widget.OpenCan();

            // ASSERT
            _widget.Should().Not.Have().Spilled().Everywhere();
        }
    }
}

这是一个很好的计划,但有些事情让我感到困惑。为什么OpenCan类可以访问TestWidget的私有成员?这不是因为它是一个嵌套类。从TestWidget中删除派生,代码将不再编译。它不能是因为它是派生类:私有范围的定义禁止派生类访问。但是,如果OpenCan同时嵌套和派生,它会以某种方式神奇地获得对TestWidget的私有成员变量的访问权。

这是该语言的故意特征,还是意外的副作用?

1 个答案:

答案 0 :(得分:3)

嵌套类或内部类可以访问封闭类的私有成员。删除继承的原因会破坏您的代码,因为没有用于访问私有成员的上下文(即,您没有用于访问实例属性/成员的TestWidget实例)。如果您在TestWidget中创建了私有静态成员,则可以从OpenCan访问这些成员,而无需继承TestWidget

成员可访问性的示例(不一定有用或不是一个好主意,但它演示了该功能):

public class Outer
{
    private int OuterProperty { get; set; }

    public class Inner
    {
        public void UpdateOuter( Outer outer, int value )
        {
            outer.OuterProperty = value;
        }
    }
}