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

C# 嵌套派生类可以访问私有成员变量,但不能访问嵌套或派生类。为什么?,c#,class,inheritance,C#,Class,Inheritance,这是受我与一位喜欢根据方案编写单元测试的客户所做工作的启发: 每个被测类别一个测试类别;每个公共方法一个嵌套类 所以测试类看起来像这样: public class TestWidget { private Mock<IDoSomething> _mockSomethingDoer = new Mock<IDoSomething>(); private Widget _widget = new Widget(_mockSomethingDoer);

这是受我与一位喜欢根据方案编写单元测试的客户所做工作的启发:

每个被测类别一个测试类别;每个公共方法一个嵌套类

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

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();
        }
    }
}
公共类TestWidget
{
private Mock_mockSomethingDoer=new Mock();
私有Widget _Widget=新Widget(_mockSomethingDoer);
公共类OpenCan:TestWidget
{
[事实]
公共void生成泡沫()
{
//安排
_mockSomethingDoer.SetUp(…);
//表演
_widget.OpenCan();
//断言
_widget.Should().Have().Generated().Froth();
}
[事实]
公共无效不适用于任何地方()
{
//安排
_mockSomethingDoer.SetUp(…);
//表演
_widget.OpenCan();
//断言
_widget.Should().Not.Have().Spilled().Everywhere();
}
}
}
这是一个很好的计划,但有点让我困惑。为什么
OpenCan
类可以访问
TestWidget
的私有成员?这并不是因为它是一个嵌套类。去掉
TestWidget
的派生,代码将不再编译。这不可能,因为它是一个派生类:私有作用域的定义本身就禁止派生类访问。但是,如果
OpenCan
既是嵌套的又是派生的,那么它就神奇地获得了对
TestWidget
的私有成员变量的访问权


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

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

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


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

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


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

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


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

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


参考:Ecma-334,17.2.6.5访问包含类型的私有和受保护成员,第275页参考:Ecma-334,17.2.6.5访问包含类型的私有和受保护成员,第275页参考:Ecma-334,17.2.6.5访问包含类型的私有和受保护成员,第275页参考:Ecma-334,17.2.6.5访问包含类型的私有和受保护构件,第275页
public class Outer
{
    private int OuterProperty { get; set; }

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