Why and how does C# allow accessing private variables outside the class itself when it's within the same containing class?

蹲街弑〆低调 提交于 2019-11-26 11:25:08

问题


I don\'t know if the question is descriptive enough but why and how does this behaviour exist?:

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

I can access layer.Children anywhere, that\'s fine, but how can I access layer.children since it\'s private?

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

only works if the code is inside the Layer class. Is there special code to treat accessing private variables differently if it\'s done inside the containing class, even though the access is from the outside?

I know the reason of using:

this.children = ...

inside the containing class, but creating new instances and modifying them from the outside, even if they are still within the containing class, doesn\'t seem like a good practice.

What\'s the reason for allowing this?


回答1:


See section 3.5.1 of the C# language specification. The relevant text is this:

Private, which is selected by including a private modifier in the member declaration. The intuitive meaning of private is “access limited to the containing type”.

Note that the modifier is relevant to the type, not the instance.

And then further in section 3.5.2 some rules are further explained:

In intuitive terms, when a type or member M is accessed, the following steps are evaluated to ensure that the access is permitted:

  • First, if M is declared within a type (as opposed to a compilation unit or a namespace), a compile-time error occurs if that type is not accessible.
  • Then, if M is public, the access is permitted.
  • Otherwise, if M is protected internal, the access is permitted if it occurs within the program in which M is declared, or if it occurs within a class derived from the class in which M is declared and takes place through the derived class type (§3.5.3).
  • Otherwise, if M is protected, the access is permitted if it occurs within the class in which M is declared, or if it occurs within a class derived from the class in which M is declared and takes place through the derived class type (§3.5.3).
  • Otherwise, if M is internal, the access is permitted if it occurs within the program in which M is declared.
  • Otherwise, if M is private, the access is permitted if it occurs within the type in which M is declared.
  • Otherwise, the type or member is inaccessible, and a compile-time error occurs.



回答2:


This is a common design. It's assumed that whoever wrote the class knows how to work with it properly and understands what it means to directly access private members. So accessing private members of other instances of the same class often works. If you are familiar with C++'s friend construct, then it's like instances of the same class are all friends with each other (although C# has no friend notion officially).

This works in C# and Java, those are the two languages I know off the top of my head. I'll bet many other languages also allow this (anyone want to chime in?)




回答3:


Remember, private access modifier says Private members are accessible only within the body of the class or the struct in which they are declared. This description is confusing but it clearly says the restriction is at class level and NOT OBJECT LEVEL. In this case, layer is still within class.

This has been discussed here before. can we access a private variable using an object



来源:https://stackoverflow.com/questions/5737602/why-and-how-does-c-sharp-allow-accessing-private-variables-outside-the-class-its

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!