当C#在同一个包含的类中时,为什么以及如何允许访问类本身之外的私有变量?

我不知道这个问题是否足够描述,但为什么以及这种行为是如何存在的?

public class Layer { public string Name { get; set; } private IEnumerable children; public IEnumerable Children { get { return this.children.Where ( c => c.Name != null ).Select ( c => c ); } set { this.children = value; } } public Layer ( ) { this.children = new List ( ); // Fine Layer layer = new Layer ( ); layer.children = new List ( ); // Isn't .children private from the outside? } } 

我可以在任何地方访问layer.Children ,这很好,但是如何访问layer.children因为它是私有的?

 Layer layer = new Layer ( ); layer.children = new List ( ); 

仅在代码位于Layer类内时才有效。 是否有特殊代码来处理访问私有变量,如果它是在包含类内完成的,即使访问来自外部?

我知道使用的原因:

 this.children = ... 

在包含类的内部,但是创建新实例并从外部修改它们,即使它们仍在包含类中,也不是一个好习惯。

允许这个的原因是什么?

请参阅C#语言规范的第3.5.1节。 相关文字是这样的:

私有,通过在成员声明中包含私有修饰符来选择。 private的直观含义是“访问仅限于包含类型”。

请注意,修饰符与类型相关,而不是与实例相关。

然后在3.5.2节进一步解释了一些规则:

直观地说,当访问类型或成员M时,将评估以下步骤以确保允许访问:

  • 首先,如果在一个类型(与编译单元或命名空间相对)中声明了M,则如果该类型不可访问则会发生编译时错误。
  • 然后,如果M是公共的,则允许访问。
  • 否则,如果M在内部受保护,则允许访问,如果它发生在声明M的程序中,或者它发生在从声明M的类派生的类中,并通过派生类类型发生(§ 3.5.3)。
  • 否则,如果M受保护,则允许访问,如果它发生在声明M的类中,或者它发生在从声明M的类派生的类中,并通过派生类类型发生(§3.5) 0.3)。
  • 否则,如果M是内部的,则允许访问,如果它发生在声明M的程序中。
  • 否则,如果M是私有的,则允许访问,如果它发生在声明M的类型中。
  • 否则,类型或成员不可访问,并发生编译时错误。

这是一种常见的设计。 假设编写该类的人知道如何正确使用它并理解直接访问私有成员的意义。 因此,访问同一类的其他实例的私有成员通常有效。 如果你熟悉C ++的friend构造,那么它就像同一个类的实例都是彼此的朋友(虽然C#没有正式的friend概念)。

这适用于C#和Java,这些是我所知道的两种语言。 我敢打赌许多其他语言也允许这样(任何人想要插入?)

请记住,私有访问修饰符说Private members are accessible only within the body of the class or the struct in which they are declared 。 这种描述令人困惑,但它清楚地表明限制是在阶级而NOT OBJECT LEVEL 。 在这种情况下,图层仍然在类中。

这已在此前讨论过。 我们可以使用对象访问私有变量吗?