2011-04-20 48 views
16

我不知道这个问题是有足够的描述,但为什么这又如何行为存在?:C#为什么以及如何在同一个包含类中访问类本身之外的私有变量?

public class Layer 
{ 
    public string Name { get; set; } 

    private IEnumerable<Layer> children; 
    public IEnumerable<Layer> Children 
    { 
     get { return this.children.Where (c => c.Name != null).Select (c => c); } 
     set { this.children = value; } 
    } 

    public Layer () 
    { 
     this.children = new List<Layer> (); // Fine 

     Layer layer = new Layer (); 
     layer.children = new List<Layer> (); // Isn't .children private from the outside? 
    } 
} 

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

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

只适用于代码在Layer类中。是否有特殊的代码来处理访问私有变量,如果它是在包含类中完成的,即使访问是从外部访问的?

我知道使用的原因:

this.children = ... 

包含类里面,但创建新实例,并从外部对其进行修改,即使他们仍然含有类中,似乎并不像一个良好的做法。

这是什么原因?

回答

20

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

私人,这是由 选择包括在 成员声明private修饰符。直觉 私有的含义是“访问受限 到包含类型”。

注意,修改是有关的类型,而不是实例。

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

直观地讲,当一个类型或 部件M被访问时,被评估以下 步骤以确保 访问被许可:

  • 首先,如果M是一个类型(相对于编译单元 或命名空间)内声明,一个编译时错误 第如果发生在类型不可访问。
  • 然后,如果M是公共的,则允许访问。
  • 否则,如果M是内部保护,访问被如果 它发生在其中 声明了M的程序中,或者如果内 发生从类中 派生的类它M被声明和发生允许 通过派生类的类型 (第3.5.3节)。
  • 否则,如果M是受保护的,则允许访问,如果它发生 ,其中M是 声明的类内,或者如果它从类派生的 类,其中 M被声明和发生通过内发生 派生类的类型(第3.5.3节)。
  • 否则,如果M是内部的,如果在声明的M为 的程序中出现 ,则允许访问。
  • 否则,如果M是私人的,如果在宣告的M为 的类型中发生 ,则允许接入。
  • 否则,该类型或成员无法访问,并发生编译时错误 。
6

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

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

3

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

这已在此处讨论过。 can we access a private variable using an object

相关问题