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