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

时间:2011-04-20 23:00:19

标签: c# .net class compiler-construction private-members

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

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 = ...

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

允许这个的原因是什么?

3 个答案:

答案 0 :(得分:24)

请参阅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的类型内   声明。
  •   
  • 否则,类型或成员不可访问,并且编译时错误   发生。
  •   

答案 1 :(得分:7)

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

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

答案 2 :(得分: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